6.3 UDP的数据传输特性和调用connect( )
2025/10/8大约 2 分钟
6.3 UDP的数据传输特性和调用connect( )
存在数据边界的UDP套接字
Information on RFC 768 » RFC Editor
User Datagram Header Format
包含有Length字段(UDP Header + payload),根据Length 确定数据边界。
发送方调用发送的次数 和 接收方调用接收的次数要相同。
测试:发送方先调用3次send,接收方等待发送方发送完毕后调用3次recv。recv 和 send 的内容按顺序对应。
实现:
sleep(20);
printf("recv \n");
for(int i=0; i<3; i++)
{
str_len = recvfrom(sock, message, BUF_SIZE, 0,
(struct sockaddr*)&client_addr, &client_addrlen);
printf("Message %d %s \n", i+1, message);
}| 行号 | 功能 | 说明 |
|---|---|---|
| 1 | 等待20s后再接收消息 |
效果:
[2025-10-06 16:46:03.363]# SEND ASCII/5 to 192.168.56.101 :56789 >>>
first
[2025-10-06 16:46:06.934]# SEND ASCII/6 to 192.168.56.101 :56789 >>>
second
[2025-10-06 16:46:12.171]# SEND ASCII/5 to 192.168.56.101 :56789 >>>
thirdming@ubuntu:/media/sf_share/Network/build$ ./Network 56789
recv
Message 1 first
Message 2 second
Message 3 third已连接UDP套接字
使用sendto()传输数据的过程:
正是因为每次发送数据都会重新注册目标地址信息,所以同一个UDP socket 可以向不同的目标地址发送消息。
如果要同一个目标主机进行长时间通信,每次sendto()时重新注册地址信息的部分降低了传输效率。通过将UDP”连接“到指定的目标地址,每次调用sendto()直接向目标地址发送数据,省掉了重新注册地址信息的过程,提高效率。
创建已连接UDP套接字
实现:
if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
unix_error("connect() error");
while(1)
{
//...
//sendto(sock, message, strlen(message), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
send(sock, message, strlen(message), 0);
}”连接“ 《=》注册 后可以直接调用send,而不是sendto 向注册的目标地址发送消息。
效果:
ming@ubuntu:/media/sf_share/Network/build$ ./Network 192.168.56.1 45454 56789
Input message(Q to quit): 1234
Input message(Q to quit): q[2025-10-06 17:15:42.724]# RECV ASCII/5 from 192.168.56.101 :56789 <<<
1234