来自 UDP 套接字的 read() 在 C 中意外丢弃数据并阻塞



我正在尝试从UDP套接字读取数据,但是在读取前255个字节后,read()似乎将其余数据放在套接字上并阻止,直到另一个数据报进入。

这是我正在使用的网络代码:

int sock;
struct sockaddr_in remote_addr, self_addr;
uint8_t network_init(uint16_t port)
{
    memset((char *) &remote_addr, 0, sizeof(remote_addr));
    remote_addr.sin_family = AF_INET;
    remote_addr.sin_addr.s_addr = inet_addr("192.168.1.22");
    remote_addr.sin_port = htons(3001);
    memset((char *) &self_addr, 0, sizeof(self_addr));
    self_addr.sin_family = AF_INET;
    self_addr.sin_addr.s_addr = INADDR_ANY;
    self_addr.sin_port = htons(3001);
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        fprintf(stderr, "Could not create socket.");
        return 1;
    }
    else if (bind(sock, (struct sockaddr *) &self_addr, sizeof(self_addr)) != 0)
    {
        fprintf(stderr, "Could not bind to socket.");
        return 1;
    }
    return 0;
}
void network_send(uint8_t *data, uint8_t len)
{
    sendto(sock, data, len, 0, (struct sockaddr *) &remote_addr, sizeof(remote_addr));
}
void read_data()
{
    int len = 0;
    ioctl(sock, FIONREAD, &len);
    // We have data
    if (len > 0)
    {
        char *buffer = (char *) malloc(256);
        uint8_t buflen;
        printf("==== %d | Data:n", len);
        while (len > 0)
        {
            buflen = min(255, len);
            len = len - buflen;
            buffer[buflen] = '';
            printf("len: %d, buflen: %d,n",len, buflen);
            read(sock, buffer, buflen);
            printf("%sn", buffer);
        }
        printf("n");
    }
}

这是我用来发送数据的命令:

echo -n '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567' | nc -u localhost 3001

这是输出:

==== 257 | Data:
len: 2, buflen: 255,
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
len: 0, buflen: 2,
^C

此外,执行此读取后,ioctl(sock, FIONREAD, &len); 生成的长度结果为 0 。我的怀疑是,出于某种原因,read()在有机会读取之前清除了其余数据,但我似乎在任何文档中都找不到任何对这种行为的引用。

我正在 Ubuntu Linux 机器上开发 ( x86_64 )。

使用 UDP 套接字,每次调用 read() 都会从内核中读取整个数据报。如果读取缓冲区对于整个数据报来说不够大,则其余部分将被丢弃。它不像流插座,您可以在其中继续通话,直到获得所有内容。

由于FIONREAD告诉您消息中的字节数,因此应将其用作malloc()的大小,而不是使用256

if (len > 0) {
    char *buffer = malloc(len);
    ...

附言我是否施放了马洛克的结果?

最新更新