AF_UNSPEC导致UDP数据包丢失

时间:2012-11-26 18:47:55

标签: c linux networking

首先请向我提出一个很长的问题 - 我正在编写一个UDP客户端 - 服务器程序,奇怪的是,每当我将此标志用于协议族时,我都会遇到此丢包问题。症状是数据包从未离开发送方主机(没有从tcpdump捕获)但sendto()返回正确的正值,该值永远不会超过200个字节。我花了很多时间来弄清楚这可以通过强制IPv4来解决,但我不明白为什么?它经过多次测试,服务器和客户端运行在同一系统(科学linux 6)上,因此常见的不可靠的UDP传输可能不是这里的原因,也没有任何防火墙规则会丢弃任何东西。我想知道是否有人碰巧知道原因?
我也想过发布一些代码,但似乎没有必要..简而言之,AF_UNSPEC导致所有UDP数据包永远不会离开发送者但没有错误,而且AF_INET一切都很完美。这可能是一个奇怪的问题,但任何见解都值得赞赏。非常感谢!
服务器初始化代码:

int udp_srv_init(char * port)
{
    struct addrinfo hints, *servinfo, *p;
    int rv;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags = AI_PASSIVE;

    if ((rv = getaddrinfo(NULL, port, &hints, &servinfo)) != 0) {
            fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
            return EXIT_FAILURE;
    }

    for(p = servinfo; p != NULL; p = p->ai_next) {
            if ((self_udp = socket(p->ai_family, p->ai_socktype,
                    p->ai_protocol)) == -1) {
                    perror("socket");
                    continue;
            }

            if (bind(self_udp, p->ai_addr, p->ai_addrlen) == -1) {
                    close(self_udp);
                    fprintf(stderr, "Port %s: ",port);
                    perror("bind");
                    continue;
            }

            break;
    }

    if (p == NULL) {
            fprintf(stderr, "server: failed to bind socket\n");
            return EXIT_FAILURE;
    }

    freeaddrinfo(servinfo);

    int buffsize = 65536; // I added this because I thought it was some buffer problem, but didn't change a thing
    setsockopt(self_udp, SOL_SOCKET, SO_RCVBUF, (void*)&buffsize, sizeof(buffsize));

    return EXIT_SUCCESS;
}

并发送:

//...
for(i=0; i<num_neighbors; i++)
{
    if(neighbors[i].cost == -1)
        continue;
    int bytes_sent = 0, ret;
    while(bytes_sent < packet_size)
    {
        if(-1 == (ret = sendto(neighbors[i].skt, (void*)&my_neighs +
                (ptrdiff_t)bytes_sent, packet_size-bytes_sent,
                0, neighbors[i].p->ai_addr, neighbors[i].p->ai_addrlen)))
        {
            perror("sendto1");
            return EXIT_FAILURE;
        }
        bytes_sent += ret;
    }
}
//....

neighbors是一个结构数组,其元素具有成员字段:

struct addrinfo *servinfo, *p;

它们是从套接字初始化获得的,而freeaddrinfo()仅在程序执行结束时调用,因此它们都是有效的。

0 个答案:

没有答案