【问题标题】:recv() failed: Bad file descriptor c++ Linuxrecv() 失败:错误的文件描述符 c++ Linux
【发布时间】:2013-09-12 07:40:14
【问题描述】:

我有问题。我的程序同时包含 10 个 TCP Server。一旦注意到来自客户端的请求,适当的 tcp 服务器套接字将接受连接并在单独的线程中处理它。我知道这不是解决我的实际问题的最有效方法,但没关系..

在 main 中,我有一个 for 循环,它将调用一个名为 Peer 的对象中的函数,即 StartThread()

for (it= ListOfPeers.begin();it!= ListOfPeers.end();it++)
{
    (*it).second->StartThread();
}

当然有一些条件会使用这个循环,但我想尽可能地缩小代码范围。

函数StartThread会在每个peer对象中被调用:

    void StartThread()
{
    pthread_t threadDoEvent;
    pthread_create( &threadDoEvent, NULL, &DoEvent_helper,this);
    pthread_detach(threadDoEvent);
}

void *DoEvent_helper( void *ptr ) // Helper to implement thread
{
    return ((Peer *)ptr)->DoEvent();
}

DoEvent 是处理请求和连接的函数:

void* DoEvent()
{
    unsigned char  buffer[1024];
    int rc;
    int    close_conn= FALSE;
    int new_sd;

    new_sd = accept(Socket, NULL, NULL);
    if (new_sd < 0)
    {
        if (errno != EWOULDBLOCK)
        {
            perror("  accept() failed");
            close_conn = TRUE;
        }
    }


    do
    {
        rc = recv(new_sd, buffer, sizeof(buffer), 0);
        if (rc < 0)
        {
            if (errno != EWOULDBLOCK)
            {
                perror("  recv() failed");
                close_conn = TRUE;
            }
            break;
        }

        if (rc == 0)
        {
            printf("  Connection closed\n");
            close_conn = TRUE;
            break;
        }

[DO SOMETHING WITH THE BUFFER]

        rc = send(new_sd, buffer, len, 0);
        if (rc <= 0)
        {
            perror("  send() failed");
            close_conn = TRUE;
            break;
        }
    }while (close_conn==FALSE);
     close(new_sd);
}

我的问题是为什么我收到一个错误:recv() failed: Bad file descriptor???? 当我在 pthread_create 和 pthread_detach 之间添加 sleep(1) 时,一切正常! 有人可以向我解释这种情况吗?或者可以帮我解决我的问题?

谢谢!

【问题讨论】:

  • 您可能想从 DoEvent 函数返回一些内容,或者您​​有未定义的行为。

标签: c++ linux sockets tcp


【解决方案1】:

好吧,即使accept 失败,你也尝试接收。这让我相信你在尝试接受之前没有正确设置被动Socket 文件描述符。

如果您在主线程中设置了Socket 描述符,那么新线程可能会在您执行此操作之前启动并运行。

【讨论】:

  • 被动套接字是在每个 Peer 的构造函数中创建的,实际上是恒定的。如果接受失败应该有一个 perror("accept() failed");接下来?我忘记了,当我启动应用程序时,它工作了几次,但过了一会儿我收到了这个 recv 错误
  • 这是否意味着我应该为我的 do while 实现一个条件?类似 if new_sd >0 ??
【解决方案2】:

确保 new_sd 在持久内存中。例如,如果它是由启动线程并退出的函数分配的,那么 new_sd 将指向垃圾。 (至少我是这样)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多