简体   繁体   中英

Determining the size of the next UDP datagram in system's queue

I want to know the size of the next UDP datagram in the system's queue.

I found this question with a similar doubt, but using boost. The last answer (as of 2010/09/23) say something about using getsockopt with the SO_NREAD option in OS X, but I can't find anything about this with Windows (using Winsock).

Here I found that I can use ioctlsocket with FIONREAD to find out what is the size of the entire queue, but I didn't find anything about the first datagram.

So my question is: Is there a way to determine what is the size of the next UDP datagram in the queue using the sockets API? (I'm not using boost).

I want my code to look like this:

char BigBuffer[ 64 * 1024 ];
void Read( void *Buf, size_t Size ) {
    size_t LengthInQueue = WhatTheSizeOfTheNextDatagram();
    if( Size < LengthInQueue ) {
         recvfrom( Socket, BigBuffer, 64*1024,  /*...*/ );
         memcpy( Buf, BigBuffer, Size );
    }
    else {
         recvfrom( Socket, Buf, size,  /*...*/ );
    }
}

I left out error checking and some parameters for the sake of space and readability. I want to avoid copying to a intermediary buffer when its not needed.

If I understand correctly, you just want to ensure that Buf doesn't overflow, but you don't care about any extra data beyond Size , since you're discarding it anyway. In that case, all you need is this:

recvfrom( Socket, Buf, size,  /*...*/ );

The remainder of the packet is automatically discarded.

Quoted from the docs :

For message-oriented sockets, data is extracted from the first enqueued message, up to the size of the buffer specified. If the datagram or message is larger than the buffer specified, the buffer is filled with the first part of the datagram, and recvfrom generates the error WSAEMSGSIZE. For unreliable protocols (for example, UDP) the excess data is lost.

您可以pop此数据报并计算其长度,要获取数据报存在信息,可以使用select函数,要获取所有数据报,可以使用带有64k缓冲区大小聚合的recv_from函数,那么此函数就是您想要的结果。

Call ioctl (ioctlsocket on windows) function with FIONREAD:

#ifdef WIN32
    if(ioctlsocket(socket, FIONREAD, &ul) == SOCKET_ERROR) {
        return -1;
    }
    return (int)ul;
#else
    int i; // ?? int ??
    if(ioctl(socket, FIONREAD, &i) == -1) {
            return -1;
    }
    return i;
#endif

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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