TCP/UDP网络编程代码梳理

一.TCP编程

TCP编程的过程:

 

1.1 Server与Clint之间通过socket建立数据通道

服务端

 

1         ServerSocket serverSocket = new ServerSocket(9999);
2         System.out.println("服务端在9999端口监听,等待连接...");
3         Socket socket = serverSocket.accept();
4         //从阻塞等待连接到accept接受连接,返回socket对象,程序继续执行
5         //注意:serverSocket可以通过调用accept();方法返回多个socket
6         //这种情况下就是多个客户端连接服务器的并发

同时客户端连接服务器:Socket socket = new Socket(InetAddress.getLocalHost(),9999);

服务端与客户端之间通过彼此的socket建立的数据通道进行数据的接收与发送

socket.getInputStream();socket.getOutputStream();
获取到输入输出流后进行对应的操作
(接受数据,IO读取,发送数据,IO输出)
1.2 数据通道传输信息-复习IO的知识:
1.2.1
字节流传输读取
getInputStream()读取与写入getOutputStream()(一次传输中,二者分别发生在客户端与服务端)
1  InputStream inputStream = socket.getInputStream();
2         byte[] bytes = new byte[1024];
3         int readLin = 0;
4         String fileName ="";
5         while ((readLin=inputStream.read(bytes))!=-1){
6             musicName =new java.lang.String(bytes,0,readLin);
7         }
8         System.out.println("服务端接受的文件名:"+fileName);
           //设置结束标记
           socket.shutdownInput();
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("要写入的信息".getBytes());

1.2.2字符流传输读取(文件)

写入

 1        OutputStream outputStream = socket.getOutputStream();
 2         /*
 3         采用字符流--OutputStream()要求转成一个writer,使用转换流OutputStreamWriter()
 4         对应的InputStream()转成一个reader,使用转换流InoutStreamReader()
 5         设置写入结束标记还可以使用:write.newLine();此时对面要求使用readline接受
 6          */
 9         BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
10         bufferedWriter.write("字符流写入");
11         bufferedWriter.newLine();//插入一个换行符,
12         // 表示结束作用上==设置了结束标记socket.shutdownOutput();
13         //此时要求对面使用readline来读----配套使用
14         bufferedWriter.flush();//使用字符流需要我们手动刷新否则数据不会写入数据通道

 

 

 

读取

1         InputStream inputStream = socket.getInputStream();
2         //复习IO读取,使用字符流
3         BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
4         String  s = bufferedReader.readLine();
5         System.out.println(s);

 

1.3关闭资源,避免浪费
inputStream.close();
outputStream.close();
socket.close();
inputStream.close();
outputStream.close();
socket.close();
serverSocket.close();
二.UDP编程
UDP网络通信编程:由类DatagramSocket和DatagramPacket(数据包)实现
接收端:通过函数
socket.receive(packet)接收到数据包packet,然后对其拆包取出数据,实现信息的接收

 1  //1. 创建一个 DatagramSocket 对象,准备在8887接收数据
 2         DatagramSocket socket = new DatagramSocket(8887);
 3         //2. 构建一个 DatagramPacket 对象,准备接收数据
 4         //   学习UDP 协议时,知道一个数据包最大 64k
 5         byte[] buf = new byte[1024*64];
 6         DatagramPacket packet = new DatagramPacket(buf, buf.length);
 7         //3. 调用 接收方法, 将通过网络传输的 DatagramPacket 对象
 8         //   填充到 packet对象
 9         //当有数据包发送到 本机的8887端口时,就会接收到数据
10         // 如果没有数据包发送到 本机的8887端口, 就会阻塞等待.
11         System.out.println("接收端A 等待接收数据..");
12         socket.receive(packet);//receive接收,填充
13 
14         //4. 可以把packet 进行拆包,取出数据,并显示.
15         int length = packet.getLength();//实际接收到的数据字节长度
16         byte[] data = packet.getData();//接收到数据
17         String s = new String(data, 0, length);
18         //打出接收的信息
19         System.out.println(s);
20         //回答问题并发送
21         System.out.println(InetAddress.getLocalHost());
22         byte [] data1 ="China".getBytes();
23         DatagramPacket datagramPacket = new DatagramPacket(data1, data1.length,
24                 InetAddress.getByName("192.168.112.1")/*InetAddress.getLocalHost()*/ ,8888);
25         //InetAddress.getLocalHost()是因为我现在在一台机器上模拟发送
26         //然后把这个datagramPacket发出去
27         socket.send(datagramPacket);
28         System.out.println("已发送完成");
29         //关闭资源
发送端:调用DatagramPacket的构造器,将信息打包成类对象,调用类的send方法,把这个数据包packet发送出去

 1         //1.创建类对象,准备在xx端口发送数据
 2         DatagramSocket datagramSocket = new DatagramSocket(8888);
 3          //2. 将需要发送的数据,封装到 DatagramPacket对象
 4         //说明: 封装的 DatagramPacket对象 data 内容字节数组 , data.length , 主机(IP) , 端口
 5         byte [] data ="中国的英语怎么说".getBytes();
 6         DatagramPacket datagramPacket = new DatagramPacket(data, data.length,
 7                 InetAddress.getByName("192.168.112.1")/*InetAddress.getLocalHost()*/ ,8887);
 8         //InetAddress.getLocalHost()是因为我现在在一台机器上模拟发送
 9         //然后把这个datagramPacket发出去
10         datagramSocket.send(datagramPacket);
11         System.out.println(InetAddress.getLocalHost());
12 
13         //准备接受答案
14         byte [] buf = new byte[1024*64];
15         DatagramPacket datagramPacket1 = new DatagramPacket(buf, buf.length);
16         datagramSocket.receive(datagramPacket1);
17         //接收到了,然后读取
18         int length = datagramPacket1.getLength();
19         byte [] data1 = datagramPacket1.getData();
20         //然后输出
21         String s = new String(data1,0,length);
22         System.out.println("答案为:"+s);
23         //关闭资源
一个疑问记录与解决:
1        DatagramPacket datagramPacket = new DatagramPacket(data, data.length,
2         InetAddress.getByName("192.168.112.1")/*InetAddress.getLocalHost()*/ ,8887);
3        //InetAddress.getLocalHost()是因为我现在在一台机器上模拟发送

 InetAddress.getByName("192.168.112.1")中因为我现在在一台机器上模拟发送,括号里应该是主机的ip,而且在idea中192.168.112.1也可以成功运行,ipconfig可知192.168.112.1是虚拟机的地址,真正的主机地址到底是什么?

 

收到的结果是

然后使用dos命令ipconfig,得到的结果是:


结合InetAddress.getLocalHost()得到是

通过查询相关资料得到了合理的解释:

 

posted @ 2022-12-12 23:25  ZitWang  阅读(281)  评论(0)    收藏  举报