2011-07-28 13 views
3

私は、UDPを使って簡単なクライアント/サーバーコードを書いています。プログラムは正常に動作しますが、クライアントを起動するだけの場合、recvfromメソッドはブロックされません。しかし、sendtoメソッドを削除すると、recvfromがブロックされます。何が起こっているの任意のアイデア?ここでC++ UDP。 recvfrom()がブロックしていないのはなぜですか?

は、クライアント側のコードです:

int server_length;      /* Length of server struct */ 
    char send_buffer[256] = "hi";   /* Data to send */ 
    time_t current_time;     /* Time received */ 

    while(true) 
    { 

     /* Tranmsit data to get time */ 
     server_length = sizeof(struct sockaddr_in); 
     if (sendto(m_oSocket, send_buffer, (int)strlen(send_buffer) + 1, 0, (struct sockaddr *)&m_oServer, server_length) == -1) 
     { 
      fprintf(stderr, "Error transmitting data.\n"); 
      continue; 
     } 

     /* Receive time */ 

     if (recvfrom(m_oSocket, (char *)&current_time, (int)sizeof(current_time), 0, (struct sockaddr *)&m_oServer, &server_length) < 0) 
     { 
      fprintf(stderr, "Error receiving data.\n"); 
      continue; 
     } 

     /* Display time */ 
     printf("Current time: %s\n", ctime(&current_time)); 

     Sleep(1000); 
    } 

そして、ここでは、初期設定である:

unsigned short m_iPortnumber; 
struct sockaddr_in m_oServer; 
struct sockaddr_in m_oClient; 
SOCKET m_oSocket; 
WSADATA w;        /* Used to open Windows connection */ 
    int a1, a2, a3, a4;      /* Server address components in xxx.xxx.xxx.xxx form */ 

    a1 = 192; 
    a2 = 168; 
    a3 = 2; 
    a4 = 14; 
    m_iPortnumber = 52685; 

    /* Open windows connection */ 
    if (WSAStartup(0x0101, &w) != 0) 
    { 
     fprintf(stderr, "Could not open Windows connection.\n"); 
     exit(0); 
    } 

    /* Open a datagram socket */ 
    m_oSocket = socket(AF_INET, SOCK_DGRAM, 0); 
    if (m_oSocket == INVALID_SOCKET) 
    { 
     fprintf(stderr, "Could not create socket.\n"); 
     WSACleanup(); 
     exit(0); 
    } 

    /* Clear out server struct */ 
    memset((void *)&m_oServer, '\0', sizeof(struct sockaddr_in)); 

    /* Set family and port */ 
    m_oServer.sin_family = AF_INET; 
    m_oServer.sin_port = htons(m_iPortnumber); 

    /* Set server address */ 
    m_oServer.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)a1; 
    m_oServer.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)a2; 
    m_oServer.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)a3; 
    m_oServer.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)a4; 

    /* Clear out client struct */ 
    memset((void *)&m_oClient, '\0', sizeof(struct sockaddr_in)); 

    /* Set family and port */ 
    m_oClient.sin_family = AF_INET; 
    m_oClient.sin_addr.s_addr=INADDR_ANY; 
    m_oClient.sin_port = htons(0); 

    /* Bind local address to socket */ 
    if (bind(m_oSocket, (struct sockaddr *)&m_oClient, sizeof(struct sockaddr_in)) == -1) 
    { 
     fprintf(stderr, "Cannot bind address to socket.\n"); 
     closesocket(m_oSocket); 
     WSACleanup(); 
     exit(0); 
    } 
+2

どのようにソケットをセットアップしていますか?関連するコードを追加できますか? – Hasturkun

+1

あなた自身に送信している可能性がありますので、 "recvfrom()"は常にデータを待機していますか? – paulsm4

+0

0以外のポートにバインドしてみてください。 –

答えて

5

sendtoが失敗する可能性があるさまざまな方法があります。 arpの失敗のようなものは、sendtoの間にエラーを引き起こします。次のソケットを使用すると、ICMP port unreachableなどのその他のものが報告されることがあります。

あなたのrecvfromコールは、実際にあなたの発信パケットに応答して送信されたICMPパケットをフェッチすることができます。

もう一度recvfromがブロックされますか?

+0

はいそうです。第2のrecvfromは実際にブロックする –

0

あなたが同じようにサーバソケットとクライアントソケットを設定しているように見えます。初期化はサーバーには適していますが、クライアントの場合はポート0にバインドしてください。

実際、両方ともINADDR_ANY(IP 0.0.0.0)をバインドしません特定のインターフェイスに接続する代わりに、正しいポートで接続を許可します。

2

ソケットが必要です。ブロック/非ブロック。

  1. BLOCKINGセット

 int nMode = 0; // 0: BLOCKING 
 
\t if (ioctlsocket (objSocket, FIONBIO, &nMode) == SOCKET_ERROR) 
 
\t { 
 
    \t \t closesocket(SendingSocket); 
 
    \t \t WSACleanup(); 
 
     return iRet; 
 
\t }

  • 設定ノンブロッキング

      int nMode = 1; // 1: NON-BLOCKING 
     
        \t if (ioctlsocket (objSocket, FIONBIO, &nMode) == SOCKET_ERROR) 
     
        \t { 
     
         \t \t closesocket(SendingSocket); 
     
         \t \t WSACleanup(); 
     
          return iRet; 
     
        \t }

  • 関連する問題