簡體   English   中英

UDP套接字中的read()會丟棄數據並在C中意外阻止

[英]read() from UDP socket drops data and blocks unexpectedly in 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] = '\0';

            printf("len: %d, buflen: %d,\n",len, buflen);

            read(sock, buffer, buflen);
            printf("%s\n", 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);
    ...

PS 我是否強制轉換malloc的結果?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM