Try to read all data from udp socket at once

Existing implementation of udp read mechanism was giving up too easily.
Replaced it with version that tries more actively to drain the entire socket buffer.

Signed-off-by: Antti Seppälä <a.seppala@gmail.com>
This commit is contained in:
Antti Seppälä 2012-06-02 14:24:29 +03:00 committed by Rolf Ahrenberg
parent c7cbde301b
commit f4126b7e2c
1 changed files with 67 additions and 63 deletions

View File

@ -154,12 +154,15 @@ int cIptvUdpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen)
error("Invalid socket in %s\n", __FUNCTION__);
return -1;
}
socklen_t addrlen = sizeof(sockAddr);
int len = 0;
// Read data from socket in a loop
do {
socklen_t addrlen = sizeof(sockAddr);
struct msghdr msgh;
struct cmsghdr *cmsg;
struct iovec iov;
char cbuf[256];
len = 0;
// Initialize iov and msgh structures
memset(&msgh, 0, sizeof(struct msghdr));
iov.iov_base = BufferAddr;
@ -171,14 +174,12 @@ int cIptvUdpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen)
msgh.msg_iov = &iov;
msgh.msg_iovlen = 1;
msgh.msg_flags = 0;
// Read data from socket
if (isActive && socketDesc && BufferAddr && (BufferLen > 0))
len = (int)recvmsg(socketDesc, &msgh, MSG_DONTWAIT);
if (len < 0) {
ERROR_IF(errno != EAGAIN, "recvmsg()");
return -1;
}
else if (len > 0) {
else
break;
if (len > 0) {
// Process auxiliary received data and validate source address
for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
if ((cmsg->cmsg_level == SOL_IP) && (cmsg->cmsg_type == IP_PKTINFO)) {
@ -218,6 +219,9 @@ int cIptvUdpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen)
}
}
}
} while (len > 0);
ERROR_IF_RET(len < 0 && errno != EAGAIN, "recvmsg()", return -1);
return 0;
}