0

私は問題があります。私のプログラムには、同時に 10 個の TCP サーバーが含まれています。クライアントからのリクエストが通知されるとすぐに、適切な tcp サーバー ソケットが接続を受け入れ、別のスレッドで処理します。これが実際の問題を解決する最も効率的な方法ではないことはわかっていますが、大丈夫です..

メインには、StartThread() である Peer というオブジェクトの関数を呼び出す for ループがあります。

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

当然、このループが使用されるいくつかの条件がありますが、できるだけコードを絞り込みたかったのです。

関数 StartThread は、各ピア オブジェクトで呼び出されます。

    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) を追加すると、すべてが機能します。誰かが私にこの状況を説明できますか? それとも私の問題を解決するのに役立ちますか?

ありがとう!

4

2 に答える 2

1

まあ失敗しても受信してみるかacceptこれにより、パッシブSocketファイル記述子を適切に設定してから受け入れようとする前に、適切に設定されていないと思います。

メインスレッドで記述子を設定するSocketと、その前に新しいスレッドが開始および実行される可能性があります。

于 2013-09-12T07:46:32.987 に答える
0

new_sd が永続メモリ内にあることを確認してください。たとえば、スレッドを起動して終了する関数によって割り当てられた場合、new_sd はジャンクを指します。(少なくとも私の場合はそうでした)

于 2013-12-13T21:42:29.503 に答える