[英]POSIX UDP socket: how is the data splitted to UDP packets?
I have a C++-Linux application that should send UDP packets in a some protocol that designed in my company. 我有一个C ++-Linux应用程序,应该以我公司设计的某种协议发送UDP数据包。
The protocol declares each chunk of the data should be attached to a header in the beginning and footer at the end, and header+data+footer should be sent as a single UDP packet to the remote end. 协议声明每个数据块都应附加到开头的标头,结尾处的页脚,并且标头+数据+页脚应作为单个UDP数据包发送到远程端。 For example: opening socket: 例如:打开插座:
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);
sending data: 发送数据:
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));
Now my questions are: 现在我的问题是:
Each sendto
creates one UDP packet (which can be fragmented into multiple IP packets, which in turn could be fragmented by the link layer, and so on). 每个sendto
都会创建一个UDP数据包(可以将其分割为多个IP数据包,而这些IP数据包又可以由链路层进行分割,依此类推)。 This is pretty much the definition of a datagram socket. 这几乎就是数据报套接字的定义。
If you have multiple buffers you want to concatenate before sending, you can use sendmsg
instead of sendto
. 如果您要在发送之前连接多个缓冲区,则可以使用sendmsg
而不是sendto
。 sendmsg
processes a struct msghdr
, which has msg_iov
and msg_iovlen
members, where you can specify an array of buffers to send. sendmsg
处理一个struct msghdr
,其具有msg_iov
和msg_iovlen
成员,可以在其中指定缓冲器阵列发送。
Richard Stevens, UNIX Network Programming , still explains all that very well. UNIX网络编程的 Richard Stevens仍然很好地解释了所有这些。
If you really want to call sendto 3 times, you have the following method 如果您确实要呼叫sendto 3次,则可以使用以下方法
Flags argument of sendto function. 标志sendto函数的参数。 flag MSG_MORE . 标志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));
Socket option of udp socket. udp套接字的套接字选项。 option UDP_CORK . 选项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.