0

私はクライアントとサーバーのプログラムを構築しています。以下は、サーバー側のメイン関数でソケットを参照するコードです。

   listenfd = socket(AF_INET, SOCK_STREAM, 0);
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
   serv_addr.sin_port = htons(5000); 

   bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); 

   listen(listenfd, 10);
   pthread_t thread[10];
   while(1)
   {
       connfd[i] = accept(listenfd, (struct sockaddr*)NULL, NULL);
       //I WANT TO GET THE IP ADDRESS HERE
       if( pthread_create(&thread[i], NULL, listener, NULL ) != 0 )
       {
           printf("Cannot create thread , exiting \n ");
           exit(-1);
       }
       i++;
   }

スレッドは次のとおりです。

void * listener( void * temp_pt )
{
    int connfdLocal=connfd[i];
    while ( (n = read(connfdLocal, recvBuff, sizeof(recvBuff)-1)) > 0)
    {
        printf("TESTING LISTENER");         
        write(connfdLocal, "TEST", strlen("TEST"));     
    }

    if(n <= 0)
    {
        printf("\n Connection lost \n");
        close(connfdLocal);
        return 0;
    } 

}

さて、私は3つの質問があります:

  1. 何らかの理由で、クライアントとの接続が閉じられるまでスレッドが「TESTING LISTENER」を出力しないため、クライアント側で接続を閉じる必要があります。同様に、文字列「TEST」がクライアントに送信されるのは、サーバー上の接続を閉じるまでではありません。なぜこうなった?どうすれば修正できますか?

  2. 接続が確立された後にクライアントの IP アドレスを取得する方法はありますか? 「ここでIPアドレスを取得したい」と入力したところ

  3. クライアント側でソケットが閉じられたときに「n」がすぐに0になるのはどうしてですか? read 関数は 1 回だけ実行され、n 値は 1 回だけ設定されていると思いました。

4

2 に答える 2

0

これは、バッファリングが原因で発生する可能性があります。したがって、 はprintf実際に呼び出されますが、テキストはstdioバッファーに置かれます。試す:

printf("TESTING LISTENER\n");
fflush(stdout);

クライアントにも同じことが言えます。

クライアントの IP アドレスを取得する方法はありますか

関数が必要ですgetpeername(2)

read 関数は 1 回だけ実行され、n 値は 1 回だけ設定されていると思いました

これは、各呼び出しで受信したバイト数です。固定値ではありません。

于 2013-03-06T17:28:02.043 に答える
0

何らかの理由で、クライアントとの接続が閉じられるまでスレッドが「TESTING LISTENER」を出力しないため、クライアント側で接続を閉じる必要があります。同様に、文字列「TEST」がクライアントに送信されるのは、サーバー上の接続を閉じるまでではありません。なぜこうなった?どうすれば修正できますか?

さらにいくつかの情報が必要になります。

  1. recvBuff はどのように定義されていますか?
  2. ヒープまたはスタックで定義されていますか?
  3. この接続をローカル コンピューターまたはリモートで確認していますか?
  4. サーバーへの書き込み時にクライアント側でエラーコードを確認しましたか?
  5. ファイアウォールの設定を確認しましたか?

接続が確立された後にクライアントの IP アドレスを取得する方法はありますか? 「ここでIPアドレスを取得したい」と入力したところ

はい、できます。accept パラメーターで「struct sockaddr&」を宣言して渡すだけです。

struct sockaddr cli_addr; 
connfd[i] = accept(listenfd, (struct sockaddr*)&cli_addr, sizeof(cli_addr));
char *connected_ip = inet_ntoa(cli_addr.sin_addr); //Client Ip Address
int port = ntohs(cli_addr.sin_port); //Client's Port

クライアント側でソケットが閉じられたときに「n」がすぐに0になるのはどうしてですか? read 関数は 1 回だけ実行され、n 値は 1 回だけ設定されていると思いました。

クライアントから受信した合計バイト数です。ソケットがリモート エンドから閉じられているため、ゼロになります。儀式から読み取るソースがない場合に何を読み取るか...

于 2013-03-06T19:16:21.790 に答える