系列文章目录
Java自学日记之网络编程(一):InetAddress和InetSocketAddress,套接字以及通信方式的实现
文章目录
前言
前文介绍了Socket套接字处理的通信,这种通信方式属于TCP通信,这里我们介绍另外一种通信方式UDP通信
一、UDP介绍(User Datagram Protocol)
相对于TCP的客户端和服务端
UDP实现数据传输的两个角色是发送端和接收端
UDP通过DatagramSocket实现数据传输,传输的数据是一个封装好的数据包DatagramPacket,数据传输的过程中不需要建立连接,当数据想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。
二、TCP vs UDP
-
UDP在传输数据时不需要建立连接
-
UDP由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等, 因此一台服务机可同时向多个客户机传输相同的消息
-
UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。
关于信息包的比较:
(1).TCP的包头结构:
源端口 16位;
目标端口 16位;
序列号 32位;
回应序号 32位;
TCP头长度 4位;
reserved 6位;
控制代码 6位;
窗口大小 16位;
偏移量 16位;
校验和 16位;
选项 32位(可选);
这样我们得出了TCP包头的最小长度,为20字节。
(2).UDP的包头结构
源端口 16位
目的端口 16位
长度 16位
校验和 16位 -
对系统资源的要求(TCP较多,UDP少)
-
UDP程序结构较简单
-
TCP采用数据流传输数据数据,UDP采用数据报模式传输数据
-
TCP保证数据正确性,UDP可能丢包
-
TCP保证数据顺序,UDP不保证
三、DatagramSocket
不同于TCP的Socket和ServerSocket,UDP中发送方和接收方都使用DatagramSocket进行发送和接收
//构造数据报套接字并将其绑定到本地主机上任何可用的端口。
public DatagramSocket() throws SocketException
//创建数据报套接字,将其绑定到指定的本地套接字地址。
public DatagramSocket(SocketAddress bindaddr) throws SocketException
//构造数据报套接字并将其绑定到本地主机上的指定端口。
public DatagramSocket(int port) throws SocketException
//创建数据报套接字,绑定到指定的本地地址
public DatagramSocket(int port, InetAddress laddr) throws SocketException
eg:
DatagramSocket datagramSocket = new DatagramSocket(8888);
四、DatagramPacket
构造方法
public DatagramPacket(byte buf[], int offset, int length)
public DatagramPacket(byte buf[], int length)
public DatagramPacket(byte buf[], int offset, int length, InetAddress address, int port)
public DatagramPacket(byte buf[], int offset, int length, SocketAddress address)
public DatagramPacket(byte buf[], int length, InetAddress address, int port)
public DatagramPacket(byte buf[], int length, SocketAddress address)
总的来说,构造一个DatagramSocket需要以下几个参数
- byte数组
- byte数组起始位置和读取长度
- 接收方的IP地址
- 接收方的端口号
eg:
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("localhost"),9999);
五、UDP通信实现的主要流程
这里以做一个简易的聊天系统为例
1.发送端
- 创建套接字datagramSocket
DatagramPacket datagramSocket = new DatagramSocket(8888);
- 准备数据包datagramPacket(假设要发送的数据是从控制台输入)
Scanner scanner = new Scanner(System.in);
System.out.print("张三:");
String str=scanner.next();
byte[] bytes=str.getBytes();
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("localhost"),9999);
- 发送数据包
datagramSocket.send(datagramPacket);
- 接收对方传回的数据(参考接收端的流程)
2.接收端
- 创建套接字
DatagramSocket datagramSocket = new DatagramSocket(9999);
- 准备一个空的数据包
byte[] bytes=new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
- 接收数据包
datagramSocket.receive(datagramPacket);
- 取出数据
byte[] data=datagramPacket.getData();
String str=new String(data,0,datagramPacket.getLength());
System.out.println("张三对我说:"+str);
- 回复对方信息(参考发送端的流程)
这些都搞完之后,再进行一些润色就行了
比如加个while循环让他们的通信请求不间断;
加一个指定的语句,只要有人发出这句话就会断开通信,比如"ByeBye"
最后出来的效果是这样的
总结
嗯,,,网络编程先学到这里了,明天开启新的篇章···
fighting!!!