获取接收包的实际大小

Get the real size of received packet

通常在发送任意大小的数据包时,会建立一个最大值并将其用作接收缓冲区的大小。

#include <winsock2.h>

// Socket Description
// Hint.ai_family = AF_INET;
// Hint.ai_socktype = SOCK_DGRAM;
// Hint.ai_protocol = IPPROTO_UDP;

void Send(int Size)
{
    char *Data = (char *)malloc(Size);
    sendto(Socket, Data, Size, NULL, Result->ai_addr, Result->ai_addrlen)
}

void Receive()
{
    const unsigned int MaxDataSize = 1436;
    char *Data = (char *)malloc(MaxDataSize);
    recvfrom(Socket, Data, MaxDataSize, 0, (SOCKADDR*)&RecvAddr, &RecvAddrSize);
}

在这个伪示例中,无论传递给 Send() 的数据大小如何,我们的 Receive() 函数总是以定义的最大大小获取它。

如何确定原始发送数据包的大小?

MSDN recvfrom() Documentation

If no error occurs, recvfrom returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

随后,通过使用 MSG_PEEK 标志:

Peeks at the incoming data. The data is copied into the buffer but is not removed from the input queue. The function subsequently returns the amount of data that can be read in a single call to the recvfrom (or recv) function, which may not be the same as the total amount of data queued on the socket. The amount of data that can actually be read in a single call to the recvfrom (or recv) function is limited to the data size written in the send or sendto function call.

这使您可以灵活地读取多个突发的传入数据包。允许您在发送数据包之前将大小值附加到数据包的开头。然而,这似乎并不像听起来那么微不足道。

我质疑采用这条路线而不是直接分配足够的内存来容纳您将要发送的最大数据包的任何性能提升。