recvfrom 函数中的错误文件描述符

Posted

技术标签:

【中文标题】recvfrom 函数中的错误文件描述符【英文标题】:Bad file descriptor in recvfrom function 【发布时间】:2016-10-21 09:31:11 【问题描述】:

这是我的 udp 服务器端代码

#include"headers.h"
int main(int argc,char **argv)

    //------------udp server socket connection------//

    int sd1;
    struct sockaddr_in serveraddr, clientaddr;
    char buffer[100];
    char *bufptr = buffer;
    int cnt=1,ret;
    socklen_t clen;
    clen=sizeof(clientaddr);

    //int buflen = sizeof(buffer);

    sd1=socket(AF_INET,SOCK_DGRAM,0);

    printf("udp socket id=%d\n",sd1);

    printf("socket created for udp..\n");

    if(sd1<0)
    
        perror("udp_sfd");
        exit(0);
    

    printf("server socket created..\n");

    serveraddr.sin_family=AF_INET;
    serveraddr.sin_port=htons(atoi(argv[1]));
    serveraddr.sin_addr.s_addr=INADDR_ANY;

    if(bind(sd1,(struct sockaddr *)&serveraddr,sizeof(serveraddr))<0)
    
        perror("bind\n");
        exit(0);
    
    else
    

        while(1)
        
            printf("server accept from client\n");

            ret=recvfrom(sd1,(char *)bufptr,strlen(buffer),0,(struct sockaddr *)&clientaddr,&clen);
            printf("ret=%d\n",ret);

            //printf("hello\n");
            if(ret<0)
            
                perror("recvfrom");
                exit(0);
            
            else
            
                printf("UDP Server received the following:\n \"%s\" message\n", bufptr);
            
            //close(sd1);
        
    

    close(sd1);
    return 0;

我正在从客户端发送缓冲区......而在服务器端它给了我这样的错误......

错误的文件描述符......我该怎么办......

我还更改了文件描述符的名称 2 次...仍然无法正常工作...

【问题讨论】:

【参考方案1】:

你的 recvfrom 很糟糕。您应该使用 sizeof(buffer) 而不是 strlen(buffer)。由于缓冲区在堆栈上,因此您可能在其中有一个大字符串,然后如果 recvfrom 获取大量数据,则会溢出缓冲区。

如果没有帮助,我会再研究一下。

【讨论】:

【参考方案2】:

问题在于您致电recvfrom

ret=recvfrom(sd1,(char *)bufptr,strlen(buffer),0,(struct sockaddr *)&clientaddr,&clen);

第三个参数应该是输入缓冲区的大小。但相反,您在缓冲区上调用strlen。因为buffer 未初始化,在其上调用strlen 正在读取未初始化的数据,这可能导致undefined behavior。

此外,除非客户端发送空终止字符串(即某些打印机字符后跟空字节),否则对 printf 的调用也将调用未定义的行为,因为读取后的任何字节都将被取消初始化。

传入缓冲区大小减 1(为空字节留出空间)而不是调用 strlen,并事先清除缓冲区。

memset(buffer, 0, sizeof(buffer));
ret=recvfrom(sd1,(char *)bufptr,sizeof(buffer)-1,0,(struct sockaddr *)&clientaddr,&clen);

【讨论】:

【参考方案3】:

我认为您正在关闭程序中其他地方的套接字。

Bad file descriptor 可能引用了无效的文件描述符,或者它在您的代码中的其他地方关闭,或者它已经在其他地方使用。我认为你需要稍微调试一下你的代码,然后好好管理你的套接字。

您的套接字可能被错误地关闭或损坏。

您也可以尝试使用不同的端口号创建新的套接字。

【讨论】:

OK 试试还是有问题,然后分享你的客户端代码。 是的...@Stubborn

以上是关于recvfrom 函数中的错误文件描述符的主要内容,如果未能解决你的问题,请参考以下文章

I/O模型

多次使用 socketpair 函数的文件描述符时出现“错误的文件描述符”错误

dup2 错误的文件描述符错误

Ruby 守护程序中的错误文件描述符

pthread_detach 上的错误文件描述符

linux之dup和dup2函数解析