1

現在、私は単一のサーバー、単一のクライアント udp チャット アプリケーションで作業しています。最初は、デフォルトの状態であるブロッキング ソケットを使用しました。ここで、ソケットをノンブロッキングに変換して、クライアントとサーバー間の通信がターンの障害なしで行われるようにしたい...サーバー側で選択機能を今のところ実装しましたが、クライアントを起動するとサーバー側に表示されるメッセージを一度送信し、その後クライアントとサーバーの両方が応答しなくなるため、サーバー側で select() 関数をどのように実装したかを示しています。

            //Declaring a non-blocking structure
              fd_set readfds,writefds;
           // clear the set ahead of time
              FD_ZERO(&readfds);
              FD_ZERO(&writefds);
           // add our descriptor to the set
              FD_SET(sd, &readfds);
              FD_SET(sd, &writefds);
              /value of sd+1
              int n=sd+1;

データの受信と送信の両方が必要なため、ループに select 関数を実装しました。

                int client_length = (int)sizeof(struct sockaddr_in);
                int rv = select(n, &readfds, NULL, NULL, NULL);
                if(rv==-1)
                {
                 printf("Error in Select!!!\n");
                 exit(0);
                }
               else if(rv==0)
                { 
                 printf("Timeout occurred\n");
                }
               else 
                if (FD_ISSET(sd, &readfds))
                {
                int bytes_received = recvfrom(sd, buffer,SIZE, 0, (struct sockaddr *)&client, &client_length);
                if (bytes_received < 0)
               {
               fprintf(stderr, "Could not receive datagram.\n");
               closesocket(sd);
               WSACleanup();
               exit(0);
              }
                }

さらにデータを送信する場合:

              fgets(buffer,SIZE,stdin);
              int rv1 = select(n, &writefds, NULL, NULL, NULL);
              if(rv1==-1)
              {
           printf("Error in Select!!!\n");
           exit(0);
              }
             else if(rv1==0)
             {
            printf("Timeout occurred\n");
             }
            else 
             if(FD_ISSET(sd,&writefds))
                  {
                     if(sendto(sd, buffer,strlen(buffer), 0, (struct sockaddr *) &client,client_length)<0)
                         {
                            printf("Error sending the file! \n");
                            exit(1);
                         }
                  }

                }

ですから、私がこれを正しく行ったかどうかを somoone が教えてくれたら本当にありがたいです。これで問題がなければ、クライアント側で同じ実装を行うことで問題が解決しますか?

4

1 に答える 1

2

これは正しくありません:

select(n, &writefds, NULL, NULL, NULL);

2 番目の引数は、可読性のみをチェックするために使用されます。書き込み可能かどうかを確認するには、3 番目の引数を使用します。

select(n, NULL, &writefds, NULL, NULL);
于 2013-04-15T06:08:51.367 に答える