1

クライアントとサーバーが UDP ソケットを使用して相互に通信できるアプリケーションを開発しました。クライアント側ではループ バック アドレスを使用し、サーバー側では INADDR_ANY を使用しました。プログラムは同じマシンで正常に動作します。しかし、別のマシンからクライアントを実行しようとすると、通信に失敗しました。コード スニペットは次のとおりです。 サーバー:

    #define PORT 8888   //The port on which to listen for incoming data
   if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
      {
         exit(EXIT_FAILURE);
      }

   ///Create a socket///
   if((socketIdentifier = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
      {                 
        //"Socket not created"
      }

   ///Socket Created///

   ///Prepare the sockaddr_in structure///
   serverSocket.sin_family = AF_INET;
   serverSocket.sin_addr.s_addr = INADDR_ANY;
   serverSocket.sin_port = htons( PORT );

   ///Bind///
   if( bind(socketIdentifier ,(struct sockaddr *)&serverSocket , sizeof(serverSocket)) == SOCKET_ERROR)
      {             
        //"Bind Failed"
      }

   ///Bind Done///
   if((recv_len = recvfrom(socketIdentifier, receiveBuffer, sizeof(receiveBuffer), 0, (struct sockaddr *) &clientSocket, &clientSocketLength)) == SOCKET_ERROR)
      {
        "Could not Receive Data"
      }
 hDeviceContext = BeginPaint(AH_Glb_windowHandle, &ps );
                TextOut(GetDC(AH_Glb_windowHandle),10,10+i,receiveBuffer,recv_len);
                EndPaint( AH_Glb_windowHandle, &ps );

クライアント:

   #define PORT 8888   //The port on which to listen for incoming data
    #define SERVER "58.65.172.11"  //ip address of udp server
      ///Initialise winsock///
       if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
          {
             //Socket Initialization Failed///
             exit(EXIT_FAILURE);
          }

       ///create socket///
       if ((socketIdentifier=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
          {
             ///Socket Creation Failed///
             exit(EXIT_FAILURE);
          }

       ///setup address structure///
       memset((char *) &connectedSocket, 0, sizeof(connectedSocket));
       connectedSocket.sin_family = AF_INET;
       connectedSocket.sin_port = htons(PORT);
       connectedSocket.sin_addr.S_un.S_addr = inet_addr(SERVER);
       if (sendto(socketIdentifier,sendBuffer,strlen(sendBuffer) , 0 , (struct sockaddr *) &connectedSocket, sizeof(connectedSocket)) == SOCKET_ERROR)
          {
             MessageBox(NULL,
                        "Sending Failed",
                        "Failure",
                        MB_ICONINFORMATION);            
             exit(EXIT_FAILURE);
          }
4

1 に答える 1

3

誰かがそれがどのように起こったのか私に説明できますか?

コードを見なくても、ルーターがポートをブロックしていると推測できます。

初め ..

サーバーが実行されているマシンのIPを見つけるために、自分のIPWebサイトを使用していました。クライアントがこのWebサイトによって生成されたIPアドレスで通信する場合、通信は機能しませんでした。

ネットワークの外部IPアドレスを提供した原因。ISPによって割り当てられたもの。ルーターはコンピューター(またはネットワーク)とインターネットの間にあり、デフォルトですべての外部インバウンド通信をブロックしています。

それで ...

しかし、ipconfigコマンドを使用してサーバーのマシンのIPを見つけたとき、見つけたIPアドレスは私のIP Webサイトによって生成されたものとは異なり、ipconfigによって生成されたサーバーのIPアドレスでクライアントから通信しようとすると、通信は機能しました。

原因ipconfigは、LAN内のルーターによって割り当てられたローカルIPを提供しました。

ルーターは、背後にあるローカルネットワークを保護するために、特に指示しない限り、すべての受信通信をフィルタリングします。

初めてサーバーに接続しようとしたときに、ルーターがブロックした外部IPアドレスを使用しました。2回目に取得したローカルIPアドレスを使用したときipconfigは、ルーターがそれらをブロックしないため、問題ありません。

これが簡単な図です...。

Client (local IP)--------
                        |
                     Router --- Internet (external IP)
                        |
Server (local IP)--------

インターネット上のどこからでもサーバーにアクセスしたい場合は、ルーターのポートを転送する必要があります。そうすれば、サーバーは外の世界から見えるようになります。ただし、サーバーマシンとアプリケーションを公開する前に、必ずサーバーマシンとアプリケーションを保護してください。

テストしているだけの場合、またはネットワーク内でのみこのサーバーを使用する場合は、ローカルIPを使用してください。また、サーバーに静的IPアドレスを割り当てて、コードを再コンパイルせずにコードで使用できるようにしてください。

于 2013-03-11T05:36:42.620 に答える