2012-02-28 3 views
1

私はthis winsock exampleを読んでいました。サーバーソケットを閉じずにC++クライアントのメインループでデータを受信するにはどうすればよいですか?

C#.NETサーバーへの永続的なTCP/IP接続を持つC++クライアントプログラムを作成する方法を概念化しようとしています。

私が見る問題は、C++クライアントが受信ループを離れるためには、サーバーがクライアントとのソケット接続を閉じる必要があることです。

私の場合、サーバーはカップル秒ごとにクライアントに送信します。サーバーからパケットを1つ受信してメインプログラムループを再開し、クライアントが残りの機能を実行できるようにする必要があります。

これはコードを受け取った場合は、C++クライアントのメインループの中で、サーバーがクライアントへの接続を閉じたことがない場合、クライアントは受信を停止することはありません。ここで

// Receive until the peer closes the connection 

do { 

    iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0); 
    if (iResult > 0) 
     printf("Bytes received: %d\n", iResult); 
    else if (iResult == 0) 
     printf("Connection closed\n"); 
    else 
     printf("recv failed with error: %d\n", WSAGetLastError()); 

} while(iResult > 0); 
+0

は*ループ内で*あなたの他の仕事を入れてください。 –

+0

SOは質問と回答のサイトであり、ブログではありません。質問がある場合は、あなたの投稿にそれを含めてください。 –

+0

ノンブロッキングソケットを使用して選択します。 –

答えて

2

はあなたから作業することを選択したプログラム例は、単一の要求を送信し、単一の応答を受信するように設計されています。接続の状態を使用して要求の終了と応答の終了を示します。

異なるサンプルプログラムから作業したい場合があります。 googleで "winsock chat example"を検索してください。あなたが求めているよう一方

は、あなたがこれを行う-whileループを置き換えることができ、このプログラムを変更するには:

// Assume that the OP's protocol sends 100-byte packets. 
// Each while iteration attempts to receive one such packet. 
// The while exits when the other side closes its connection. 
while(1) { 
    // Receive 100-byte packet 
    int receivedBytes; 
    for(receivedBytes = 0; receivedBytes < 100;) { 
     int iResult = recv(ConnectSocket, 
          recvbuf+receivedBytes, 
          recvbuflen-receivedBytes, 0); 

     if (iResult > 0) { 
      receivedBytes += iResult; 
      printf("Bytes received: %d\n", iResult); 
     } else if (iResult == 0) { 
      printf("Connection closed\n"); 
      break; 
     } else { 
      printf("recv failed with error: %d\n", WSAGetLastError()); 
      break; 
     } 
    } 
    if(receivedBytes == 100) { 
     // ... process packet here 
    } else { 
     break; 
    } 
} 
+0

返事をいただきありがとうございます。私はwinsockのチャットの例を調べます。 – Mausimo

1

問題は、あなたがに方法がありませんということですrecv()が返すところを知っています。 5つの回避策があります。

  1. ソケットを非ブロックにします。 (推奨しません)
  2. select()をタイムアウトで使用してください。
  3. 非同期ソケットを使用します。これはおそらく最も速い方法ですが、より複雑です。
  4. スレッドを使用してください。
  5. BSDのkqueueの
+0

#1と#3のポイントは完全に相互排他的です。また、投票、/ dev/poll、epoll、イベントポートを追加することもできます。 –

関連する問題