java 网络通信_java-网络通信相关

a8f1acbdac304a280b381fee7b70b4fd.png

java中

5a36ca31ed24177d6b8a355b53dc8418.png

Socket类

df52b5af8d2d5a19244559af2b60dd56.png

importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;importjava.net.Socket;public classClient {public static void main(String[] args) throwsIOException {//创建socket,指定服务器的ip 和端口

Socket socket = new Socket("127.0.0.1",8888);//从socket里面获取字节输出流,准备给服务器发送数据

OutputStream ops =socket.getOutputStream();

ops.write("你好,全植强的服务器".getBytes());//没有服务器会抛出异常:thread "main" java.net.ConnectException: Connection refused: connect//获取字节输入流,接受来自服务器的回馈数据

InputStream ips =socket.getInputStream();byte[] bytes = new byte[1024];//创建接受字节数组,数组长度初定为

int len = ips.read(bytes);//将数据读入数组,返回数组的长度

System.out.println(new String(bytes,0,len));//输出数据

socket.close();

}

}

ServerSocket类

c71bd3beebde22bcf19ce925691f682e.png

importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;importjava.net.ServerSocket;importjava.net.Socket;public classServer {public static void main(String[] args) throwsIOException {//创建ServerSocket 指定端口号,不指定就有系统随机安排!!

ServerSocket server = new ServerSocket(8888);//监听获取客户端的socket

Socket socket=server.accept();//从获取到客户端的socket创建字节输入流,准备读取客户端发来的数据

InputStream ips =socket.getInputStream();byte[] bytes = new byte[1024];int len = ips.read(bytes);//将数据读入数组,返回数据的长度

System.out.println(new String(bytes,0,len));

OutputStream ops=socket.getOutputStream();

ops.write("收到小弟".getBytes());

socket.close();

server.close();

}

}

TCP文件上传是咧

e34576ca489e10b39ce59984fae8fb02.png

FileClient

374f43a7f82751d1d1825bd60f18ebe2.png

/*文件上传的客服端,读取本地文件,上传到服务器,读取服务器回写的数据

数据源:Snipaste_2020-06-25_23-37-15.png

目的地:服务器*/

public classTcpSocketFileClient {public static void main(String[] args) throwsIOException {

FileInputStream fis= new FileInputStream("Snipaste_2020-06-25_23-37-15.png");

Socket socket= new Socket("127.0.0.1",8888);

OutputStream os=socket.getOutputStream();int len = 0;byte[] bytes = new byte[1024];/*@return the total number of bytes read into the buffer, or

* -1 if there is no more data because the end of

* the file has been reached.*/

while ((len = fis.read(bytes)) != -1){

System.out.println(len);

os.write(bytes,0,len);

}

InputStream ips=socket.getInputStream();while ((len = ips.read(bytes)) != -1){

System.out.println(new String(bytes,0,len));

}

fis.close();

socket.close();

}

}

FileServer::

8d1104702012bafeaa05a214ccf6df48.png

importjava.io.File;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.net.ServerSocket;importjava.net.Socket;public classTcpSocketFileServer {public static void main(String[] args) throwsIOException {//创建服务器socket指定端口号

ServerSocket server = new ServerSocket(8888);//监听客户端,获取socket

Socket socket =server.accept();//获取socket中的字节输入流,读取客户端传进来的数据

InputStream ips =socket.getInputStream();//判断文件对象是否存在

File file = new File("d:\\upload");if(!file.exists()){

file.mkdir();

}//获取本地文件输出字节流,准备将从客户端获取到的文件写出到本地磁盘中

FileOutputStream fops = new FileOutputStream(file+"\\up.png");//读取客户端发来的输入字节流

int len = 0;byte[] bytes = new byte[1024];while ((len = ips.read(bytes))!= -1){//网本地输出字节流写入客户端的数据

fops.write(bytes,0,len);

}//使用socket中的字节输出字节流往客户端输出数据

socket.getOutputStream().write("done".getBytes());

fops.close();

socket.close();

server.close();

}

}

运行服务器再运行客户端最后发现:

4a94d3f3d1d794d01eb031bb77691276.png

当时两个程序都没有停止下来,为什么:

182190e82e777b3b7980074b5cb66445.png

解决方法;

a5949a428a456d26995d5047df486b43.png

客户端加入:

37e00428d64c4599fb0f9e4beac613f8.png

结果,两个程序都结束,client也收到结果:

7df1b15f56b132e4f84bcfacb962898c.png

优化服务端

/*优化,自定义一个文件的命名规则,防止同盟的文件被覆盖掉

规则:域名+毫秒数+随机数*/String filename= "\\better.quan"+System.currentTimeMillis()+new Random().nextInt(787878)+".png";

FileOutputStream fops= new FileOutputStream(file+filename);//读取客户端发来的输入字节流

int len = 0;byte[] bytes = new byte[1024];while ((len = ips.read(bytes))!= -1){//网本地输出字节流写入客户端的数据

fops.write(bytes,0,len);

}

结果:

97249abddf0197c0f5ac4e4b552aff0c.png

优化2:让服务器不停下,持续监听,客户端就能不断上传文件:

/*让服务器一直处于监听状态(死循环accept方法)

有一个客户端上传文件,就保存一个文件*/

while (true){

Socket socket=server.accept();//获取socket中的字节输入流,读取客户端传进来的数据

InputStream ips =socket.getInputStream();//判断文件对象是否存在

File file = new File("d:\\upload");if(!file.exists()){

file.mkdir();

}//获取本地文件输出字节流,准备将从客户端获取到的文件写出到本地磁盘中

/*优化,自定义一个文件的命名规则,防止同盟的文件被覆盖掉

规则:域名+毫秒数+随机数*/String filename= "\\better.quan"+System.currentTimeMillis()+new Random().nextInt(787878)+".png";

FileOutputStream fops= new FileOutputStream(file+filename);//读取客户端发来的输入字节流

int len = 0;byte[] bytes = new byte[1024];while ((len = ips.read(bytes))!= -1){//网本地输出字节流写入客户端的数据

fops.write(bytes,0,len);

}//使用socket中的字节输出字节流往客户端输出数据

socket.getOutputStream().write("done".getBytes());

fops.close();

socket.close();

}//不用关闭服务器//server.close();

多次启动客户端

4408be98c0fb9c247728e810e1250449.png

优化三:提高效率,利用多线程

来一个客户端上传文件请求,开启一个线程去处理

public classTcpSocketFileServer {public static void main(String[] args) throwsIOException {//创建服务器socket指定端口号

ServerSocket server = new ServerSocket(8888);//监听客户端,获取socket

/*让服务器一直处于监听状态(死循环accept方法)

有一个客户端上传文件,就保存一个文件*/

while (true) {

Socket socket=server.accept();//获取socket中的字节输入流,读取客户端传进来的数据

/*使用多线程,提高程序的效率

有一个客户端上传文件,就开启一个线程,完成文件的上传*/

new Thread(newRunnable() {

@Overridepublic voidrun() {try {//由于接口类当中没有throw异常,使用try catch

InputStream ips =socket.getInputStream();//判断文件对象是否存在

File file = new File("d:\\upload");if (!file.exists()) {

file.mkdir();

}//获取本地文件输出字节流,准备将从客户端获取到的文件写出到本地磁盘中

/*优化,自定义一个文件的命名规则,防止同盟的文件被覆盖掉

规则:域名+毫秒数+随机数*/String filename= "\\better.quan" + System.currentTimeMillis() + new Random().nextInt(787878) + ".png";

FileOutputStream fops= new FileOutputStream(file +filename);//读取客户端发来的输入字节流

int len = 0;byte[] bytes = new byte[1024];while ((len = ips.read(bytes)) != -1) {//网本地输出字节流写入客户端的数据

fops.write(bytes, 0, len);

}//使用socket中的字节输出字节流往客户端输出数据

socket.getOutputStream().write("done".getBytes());

fops.close();

socket.close();

}catch(FileNotFoundException e) {

e.printStackTrace();

}catch(IOException e) {

e.printStackTrace();

}

}

}).start();//不用关闭服务器//server.close();

}

}

}

模拟B\S服务器

//BS服务器版本TCP服务器

public classBsTcpServer {public static void main(String[] args) throwsIOException {

ServerSocket server= new ServerSocket(8080);

Socket socket=server.accept();

InputStream ips=socket.getInputStream();byte[] bytes = new byte[1024];int len = 0;while ((len = ips.read(bytes))!= -1){

System.out.println(new String(bytes,0,len));

}

}

}

运行并访问

52aa7c802d136669204d70e93cbc94c4.png

服务器输出为:

GET /testCOM.html HTTP/1.1 //地址请求的资源位置Host: localhost:8080Connection: keep-alive

Cache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36 Edg/83.0.478.54Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

Sec-Fetch-Site: cross-site

Sec-Fetch-Mode: navigate

Sec-Fetch-User: ?1

Sec-Fetch-Dest: document

Accept-Encoding: gzip, deflate, br

Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6

Cookie: goSessionid=xf82SLPFkJGHj5qZcl_lsO6XFT-FTHwjgVlxkkQdzWs%3D

GET /testCOM.html HTTP/1.1 可以使用BufferReader的方法readline读取一行

new BufferedReader(new InputStreamReader(is)) 将网络字节输入流转换为字符缓冲输入流

再使用String 类方法split(" ") 切割字符串,获取中间的部分

再使用String的方法substring(1)获取html文件的路径

testCOM.html

然后服务器建立一个本地字节输入流,根据获取到的文件路径读取html文件

服务器使用网络字节输出流把读取到的文件写道客户端即浏览器显示

固定的浏览器写入:

//写入HTTP协议响应投,固定写法

out.write("HTTP/1.1 200 OK\r\n".getBytes());

out.write("Content-Type:text/html\r\n".getBytes());//必须写入空行

out.write("\r\n".getBytes());

Server辰戌:

import java.io.*;importjava.net.ServerSocket;importjava.net.Socket;//BS服务器版本TCP服务器

public classBsTcpServer {public static void main(String[] args) throwsIOException {

ServerSocket server= new ServerSocket(8080);

Socket socket=server.accept();

InputStream ips=socket.getInputStream();//byte[] bytes = new byte[1024];//int len = 0;//while ((len = ips.read(bytes))!= -1){//System.out.println(new String(bytes,0,len));//}

BufferedReader br =new BufferedReader(newInputStreamReader(ips));

String line= br.readLine();//GET /resources/testCOM.html HTTP/1.1

String[] strings = line.split(" ");///resources/testCOM.html

String htmlpath = strings[1].substring(1);//resources/testCOM.html

FileInputStream fips= new FileInputStream(htmlpath); //resources/testCOM.html

OutputStream ops=socket.getOutputStream();//写入HTTP协议响应投,固定写法

ops.write("HTTP/1.1 200 OK\r\n".getBytes());

ops.write("Content-Type:text/html\r\n".getBytes());//必须写入空行

ops.write("\r\n".getBytes());int len = 0;byte[] bytes = new byte[1024];while ((len = fips.read(bytes)) != -1){

ops.write(bytes,0,len);

}

fips.close();

socket.close();

server.close();

}

}

结果:

7db7e47ca8b15d73c7a38d064080ad8c.png

9199319e3cc4d9943e3191d9cf327ee1.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值