1

同じ IP アドレスを持つ同じマシン上で C でマルチスレッド クライアント サーバー ソケット プログラミングを実装していますが、クライアントとサーバーのポートは異なります。C 環境で pthread の概念を使用して実装しました。しかし、「accept()」ルーチンに到達すると、サーバー スレッドが停止しているのに対し、クライアント スレッドが実行されていることしかわかりません。何が問題なのだろうと思っています。誰かが私がどこを間違えているかを知ることができれば、それは本当に役に立ちます

私のクライアントコードは次のようになります。

void *client_connect(void *arg)
{

   int client_socket;
   struct sockaddr_in Serv_Addr;
   struct sockaddr_in Client_Addr;
   int addrlen=sizeof(Client_Addr);

   char send_buffer_client[] = {"server message"};
   char recv_buffer_client[1024];
   int nbytes;

   client_socket = lwip_socket(AF_INET, SOCK_STREAM, 0);
   if (client_socket < 0) ;

   memset((char *)&Serv_Addr, 0, sizeof(Serv_Addr));
   Serv_Addr.sin_family = AF_INET;
   Serv_Addr.sin_len = sizeof(Serv_Addr);
   Serv_Addr.sin_addr.s_addr = inet_addr("1.2.3.4");
   Serv_Addr.sin_port = 9999;
   memset((char *)&Client_Addr, 0, sizeof(Client_Addr));
   Client_Addr.sin_family = AF_INET;
   Client_Addr.sin_len = sizeof(Client_Addr);
   Client_Addr.sin_addr.s_addr = inet_addr("1.2.3.4");
   Client_Addr.sin_port = 5555;

   lwip_connect(client_socket, (struct sockaddr *)&Serv_Addr, sizeof(Serv_Addr));

   while (1) {

               do{
                   nbytes = lwip_recv(client_socket, recv_buffer_client, sizeof(recv_buffer_client),0);
                   if (nbytes>0) lwip_send(client_socket, send_buffer_client, sizeof(send_buffer_client), 0);

                   printf("server message = %s\n", recv_buffer_client);
               }  while (nbytes>0);

               sleep(10);

       }
       lwip_close(client_socket);
}

私のサーバーコード:

void *server_connect(void *arg)
{

   int server_socket;
   struct sockaddr_in Serv_Addr;
   struct sockaddr_in Client_Addr;
   int addrlen=sizeof(Client_Addr);
   int clientfd;
   char send_buffer[] = {"Server message"};
   char recv_buffer[1024];
   int nbytes_server, client_length;

   server_socket = lwip_socket(AF_INET, SOCK_STREAM, 0);
   if (server_socket < 0)
   printf("could not create server socket");
   else
   printf("created SERVER socket");

   memset((char *)&Serv_Addr, 0, sizeof(Serv_Addr));
   Serv_Addr.sin_family = AF_INET;
   Serv_Addr.sin_len = sizeof(Serv_Addr);
   Serv_Addr.sin_addr.s_addr = inet_addr("1.2.3.4");
   Serv_Addr.sin_port = 9999;


   client_length = sizeof(Client_Addr);
   if (lwip_bind(server_socket, (struct sockaddr *)&Serv_Addr, sizeof(Serv_Addr)) < 0) {           
           printf("could not BIND");
   }

   if ( lwip_listen(server_socket, 20) != 0 ){
            printf("could not BIND");
   }
   while (1) {
                lwip_accept(server_socket, (struct sockaddr*)&Client_Addr, &client_length);                

               do{
                nbytes_server = lwip_recv(server_socket, recv_buffer, sizeof(recv_buffer),0);
                if (nbytes_server>0){lwip_send(server_socket, send_buffer, sizeof(send_buffer), 0);}

                printf("client message = %s\n", recv_buffer);
                }while(nbytes_server>0); 
                sleepms(10);
       }
       lwip_close(server_socket);
}

void main(void)
{
    pthread_t  client_thread;
    pthread_t  server_thread;

    pthread_create(&server_thread, NULL, server_connect, NULL);
    pthread_create(&client_thread, NULL, client_connect, NULL);

    while(1){
        sleepms(1);
        }
}

やり方が間違っていたら教えてください

よろしくデブ

4

3 に答える 3

2

少なくとも 3 つのエラーがあります。

lwip_accept() は新しいソケット記述子を返します。元のサーバー ソケットからではなく、クライアントから読み取るために使用する必要があります (誰かが実際にサーバーに接続するまで lwip_accept がブロックされることにも注意してください)。

少しエンディアンのマシンを使用している場合、ポート番号もオフになる可能性があります。通常、それらはネットワークバイトオーダーになってい Serv_Addr.sin_port = htons(9999);ます。クライアントポートについても同じようにする必要があります-htonsは、ホストエンディアンからネットワークエンディアンに短縮を変換します

データを送信していません。クライアントは、サーバーが何かを送信するのを待ちます。しかし、サーバーは何も送信せず、クライアントが何かを送信するのを待ちます。何も起こりません。

lwip_connect も失敗するかどうかを確認し、環境が提供する場合はerrnoを調べます。何が問題なのかの手がかりになる可能性があります。

于 2011-05-04T17:06:50.817 に答える
0

同じマシンを使用している場合、使用している IP アドレス 1.2.3.4 は localhost の一般的なアドレスではなく、127.0.0.1 である必要があります。ルーターなどを使用してマシンの IP アドレスを実際に IP アドレス 1.2.3.4 にしない限り、そのアドレスは解決されず、クライアントとサーバーを同じマシンで実行しようとしても、ネットワーク上の特定のマシンに 1.2.3.4 を解決する方法がないため、お互いを見つけることはできません。

また、サーバーを特定の IP アドレスにロックする必要はありません。定数INADDR_ANYを使用するだけnetinet/in.hで、ソケットをシステム上の任意のインターフェイスにバインドできます。クライアント側では正しい IP アドレスが必要ですが、ローカルホストの場合は 127.0.0.1 を使用できます。

于 2011-05-04T15:28:34.427 に答える
0

(1) クライアントとサーバーの両方が、エコー バックする前に何かを受信するのを待っているように見えます。誰かが最初に話さなければなりません。

(2) あなたの lwip_accept が、クライアントと通信するための新しいソケットを返す場所がわかりません。リッスンしているソケットで recv/send を実行することになります。

(3)ここでもコードを検討してください:

while (1)
{
    lwip_accept(server_socket, (struct sockaddr*)&Client_Addr, &client_length);

    do
    {
        nbytes_server = lwip_recv(server_socket, recv_buffer, sizeof(recv_buffer), 0);

        if (nbytes_server > 0)
        {
            lwip_send(server_socket, send_buffer, sizeof(send_buffer), 0);
        }

        printf("client message = %s\n", recv_buffer);
    }
    while (nbytes_server > 0);

    sleepms(10);
}

メッセージを読んでエコーしますが、ソケットを閉じることはありません (これはリッスン ソケットであるため、おそらく賢明です!)。クライアントが再び接続しない場合、その受け入れは永久にブロックされます。

(4) それらの sleepms() 呼び出しは必要ありません。メインで pthread_join() を使用し、残りを取り除くだけです。とにかく、すべての通話がブロックされているようです。

于 2011-05-04T16:44:26.240 に答える