Reputation: 4175
I have a C++-Linux application that should send UDP packets in a some protocol that designed in my company.
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. 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:
Upvotes: 0
Views: 974
Reputation: 89
If you really want to call sendto 3 times, you have the following method
Flags argument of sendto function. flag 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. option 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));
Upvotes: 1
Reputation: 33719
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). 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
processes a struct msghdr
, which has msg_iov
and msg_iovlen
members, where you can specify an array of buffers to send.
Richard Stevens, UNIX Network Programming, still explains all that very well.
Upvotes: 2