在 recvfrom 函数中出现了坏的文件描述符

4

这是我用于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;
}

我正在从客户端发送缓冲区,但在服务器端会出现以下错误:
坏的文件描述符...我该怎么办...
我已经两次更改了文件描述符的名称...但仍然无法正常工作...
3个回答

1
你的recvfrom有问题。你应该使用sizeof(buffer)而不是strlen(buffer)。由于buffer在堆栈上,你可能会有一个很大的字符串,如果recvfrom获取大量数据,那么就会溢出缓冲区。
如果这不能解决问题,我会再进一步研究它。

1
问题出在您对 recvfrom 的调用上:
ret=recvfrom(sd1,(char *)bufptr,strlen(buffer),0,(struct sockaddr *)&clientaddr,&clen);

第三个参数应该是输入缓冲区的大小。但是你却在缓冲区上调用了strlen。因为buffer未初始化,调用strlen会读取未初始化的数据,这可能导致未定义行为
另外,除非客户端发送了一个以空字节结尾的字符串(即一些打印字符后跟着一个空字节),否则调用printf也会产生未定义的行为,因为读取的字节之后的任何字节都将未初始化。
传递缓冲区大小减1(留出空间放置空字节)而不是调用strlen,并在此之前清除缓冲区。
memset(buffer, 0, sizeof(buffer));
ret=recvfrom(sd1,(char *)bufptr,sizeof(buffer)-1,0,(struct sockaddr *)&clientaddr,&clen);

0

我认为你在程序的其他地方关闭了套接字。

坏文件描述符可能指的是无效的文件描述符,或者它在代码的其他地方被关闭,或者已经在其他地方被使用。我认为你需要对代码进行一些调试,然后很好地管理你的套接字。

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

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


如果您尝试了仍然遇到问题,请分享您的客户端代码。 - Stubborn
是的...@固执 - Milan Shah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接