POSIX UDP套接字:如何将数据分割为UDP数据包?

时间:2018-02-07 10:59:01

标签: linux sockets networking udp posix

我有一个C ++ - Linux应用程序,它应该在我公司设计的某个协议中发送UDP数据包 协议声明每个数据块应该连接到开头和页脚的头部,而header + data + footer应该作为单个UDP数据包发送到远程端。例如: 开口插座:

struct hostent *udphost;
udphost = gethostbyname(_remoteIp.c_str());
if(udphost == NULL)
{
  ESPFS_DEBUG ("invalid host address format\n" );
  return;
}

bzero((char *) &_udpSockAddr, sizeof(_udpSockAddr));
_udpSockAddr.sin_family = AF_INET;
bcopy((char *)udphost->h_addr, (char *)&_udpSockAddr.sin_addr.s_addr, udphost->h_length);
_udpSockAddr.sin_port = htons(UDP_PORT);

发送数据:

protocol_header hdr;  
protocol_footer ftr;    
sendto(_udpSocket, hdr, sizeof(hdr), 0, (const struct sockaddr *)&_udpSockAddr, sizeof(_udpSockAddr));  
sendto(_udpSocket, data, data_size, 0, (const struct sockaddr *)&_udpSockAddr, sizeof(_udpSockAddr));  
sendto(_udpSocket, ftr, sizeof(ftr), 0, (const struct sockaddr *)&_udpSockAddr, sizeof(_udpSockAddr)); 

现在我的问题是:

  1. 每个sendto是否转换为单个UDP数据包?我的意思 这里有三个UDP包吗?如果是的话,它在哪里记录?我找不到 任何提及。
  2. 如果没有,我如何定义posix什么是包给我?
  3. 如何将多个缓冲区作为单个UDP数据包发送,任何想法?

2 个答案:

答案 0 :(得分:2)

每个sendto创建一个UDP数据包(可以将其分段为多个IP数据包,而这些数据包又可以通过链路层进行分段,依此类推)。这几乎就是数据报套接字的定义。

如果您想在发送前连接多个缓冲区,则可以使用sendmsg代替sendtosendmsg处理struct msghdr,其中包含msg_iovmsg_iovlen个成员,您可以在其中指定要发送的缓冲区数组。

理查德史蒂文斯, UNIX网络编程,仍然很好地解释了这一切。

答案 1 :(得分:1)

如果你真的想打三次发送到,你有以下方法

方法1

发送函数的标志参数。标记 MSG_MORE

sendto(_udpSocket, hdr, sizeof(hdr), MSG_MORE, (const struct sockaddr *)&_udpSockAddr, sizeof(_udpSockAddr));  
sendto(_udpSocket, data, data_size, MSG_MORE, (const struct sockaddr *)&_udpSockAddr, sizeof(_udpSockAddr));  
sendto(_udpSocket, ftr, sizeof(ftr), 0, (const struct sockaddr *)&_udpSockAddr, sizeof(_udpSockAddr));

方法2

udp socket的套接字选项。选项 UDP_CORK

int zero = 0;
int one = 1;
setsockopt(_udpSocket, IPPROTO_UDP, UDP_CORK, &one, sizeof(one));
sendto(_udpSocket, hdr, sizeof(hdr), 0, (const struct sockaddr *)&_udpSockAddr, sizeof(_udpSockAddr));  
sendto(_udpSocket, data, data_size, 0, (const struct sockaddr *)&_udpSockAddr, sizeof(_udpSockAddr));  
sendto(_udpSocket, ftr, sizeof(ftr), 0, (const struct sockaddr *)&_udpSockAddr, sizeof(_udpSockAddr));
setsockopt(_udpSocket, IPPROTO_UDP, UDP_CORK, &zero, sizeof(zero));