繁体   English   中英

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

[英]POSIX UDP socket: how is the data splitted to UDP packets?

我有一个C ++-Linux应用程序,应该以我公司设计的某种协议发送UDP数据包。
协议声明每个数据块都应附加到开头的标头,结尾处的页脚,并且标头+数据+页脚应作为单个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数据包发送?

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

如果您要在发送之前连接多个缓冲区,则可以使用sendmsg而不是sendto sendmsg处理一个struct msghdr ,其具有msg_iovmsg_iovlen成员,可以在其中指定缓冲器阵列发送。

UNIX网络编程的 Richard Stevens仍然很好地解释了所有这些。

如果您确实要呼叫sendto 3次,则可以使用以下方法

方法1

标志sendto函数的参数。 标志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套接字的套接字选项。 选项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));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM