recvfrom() 即使是第一次调用中的 UDP 消息,也不会填充来自 IP 地址

Posted

技术标签:

【中文标题】recvfrom() 即使是第一次调用中的 UDP 消息,也不会填充来自 IP 地址【英文标题】:recvfrom() not filling the from IP address even for UDP messages in first call 【发布时间】:2014-06-21 18:12:06 【问题描述】:

我正在使用 recvfrom() 将 UDP 数据报放入我的缓冲区并传递非 NULL from_addr 结构和 len 参数,期望它获取源 IP。但是对于第一次调用,它们是 NULL。 随后的调用正在填充 addr 结构和 len 字段。这是预期的吗?

#include <stdio.h>
#include <string.h>

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>


int
main()

    struct  sockaddr_in myaddr, from_addr;
    char    from_ip[1024] = "", myip[2014] = "";
    char    rmsg[1024 * 1024] = "";
    int     sock_fd=-1,nbytes=0;
    int     len=0;
    unsigned short port=0;

    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sock_fd == -1)
    
        perror("Socket");
        return -1;
    

    printf("IP Addr & Port to bound to :");
    scanf("%s%u", myip, &port);

    myaddr.sin_family = AF_INET;
    myaddr.sin_port = htons(port);
    inet_pton(AF_INET, myip, &myaddr.sin_addr);

    printf("Bound to %s:%u\n", myip, htons(port));

    nbytes = bind(sock_fd, &myaddr, sizeof(myaddr));
    if(nbytes == -1)
    
        perror("Bind");
        return -1;
    

    do
    
        /**/nbytes = recvfrom(sock_fd, rmsg, sizeof(rmsg), 0, &from_addr, &len);/**/
        inet_ntop(AF_INET, &from_addr.sin_addr, from_ip, sizeof(from_ip));

        printf("Received %d bytes from %s@%d : %s\n", nbytes, from_ip, ntohs(from_addr.sin_port), rmsg);

        if(strcmp(rmsg, "Bye") == 0)
        
            printf("Client Disconnected.\n");
        
        memset(rmsg, 0, sizeof(rmsg));
    while(1);

    return 0;

输出:

-------------------------------OutPut -----------------------------------------
root@ubuntu:/home/akumarkk/Desktop/distributedComp_Project/test# ./userver 
IP Addr & Port to bound to :127.0.0.1 12
Bound to 127.0.0.1:3072
Received 2 bytes from 0.0.0.0@0 : hi
Received 6 bytes from 127.0.0.1@49511 : second
Received 7 bytes from 127.0.0.1@49511 : message
Received 3 bytes from 127.0.0.1@49511 : Bye
Client Disconnected.

【问题讨论】:

len 应输入 socklen_t 而不是 int,尤其是在使用其地址时。 OT: recvfrom() 返回 ssize_t 而不是 int 【参考方案1】:

你必须在调用recvfrom之前填写len,你不能离开0

len = sizeof from_addr;
nbytes = recvfrom(sock_fd, rmsg, sizeof(rmsg), 0, &from_addr, &len);

【讨论】:

还建议测试inet_ntop 的结果,以便能够正确解释(此处:打印)返回的值。

以上是关于recvfrom() 即使是第一次调用中的 UDP 消息,也不会填充来自 IP 地址的主要内容,如果未能解决你的问题,请参考以下文章

【奇】udp的recvfrom

UDP中的recvfrom没有得到任何东西

UDP 套接字上的 recvfrom() 返回 -1 但 WSAGetLastError() 返回 0

UDP和套接字,recvfrom()返回-1,资源暂时不可用

关于UDP数据报引发“异步错误”的疑问

(十四)UDP协议的两个主要方法sendto和recvfrom详解