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()得到是

通过查询相关资料得到了合理的解释:
![]()


浙公网安备 33010602011771号