2010-11-22 9 views
2

2分ごとにサーバーからデータを受信する次の機能セットアップがあります。初めて私は機能すると思われますが、決して返さないrecvコールでフリーズします。サーバーに何も送信しなくても各呼び出しでバッファを割り当てる必要がありますか?recvサーバーからの着信トラフィック

#define RCVBUFSIZE 32 

void Receive() 
{ 
    UINT totalBytesRcvd = 0, bytesRcvd = 0; 
    char buffer[RCVBUFSIZE];  /* Buffer for string */ 

    /* Receive up to the buffer size (minus 1 to leave space for 
    a null terminator) bytes from the sender */ 

    bytesRcvd = recv(sockClient, buffer, RCVBUFSIZE - 1, 0); 

    if (bytesRcvd) 
    { 
     buffer[bytesRcvd] = '\0'; 
     MessageBox(0, buffer, 0, 0); //some way to display the received buffer 
    } 
    else if (bytesRcvd == SOCKET_ERROR) 
    { 
     return; 
    } 
} 
+2

注:あなた '(bytesRcvdが)'チェックはあなたがしようとする書きますつまり、条件(-1) 'SOCKET_ERROR'を満たす場合「バッファ[-1]'エラーが発生した場合と、続いてボロックに着きなさい! –

答えて

5

(1)バッファは実際には割り当てられていないため、スタック上に存在します。通常は、スタック上で32バイトを使用することを心配する必要はありません。

(2)recvは、何か受信するまでブロックすることになっています。ノンブロッキングソケットを使用するか、selectを使用して回避することができます。参考までにhereをご覧ください。特に

、あなたは

(2A)非ブロックモードにあなたのソケットを設定するioctlsocketを使用して。その後、readと呼び出しても何も読まない場合は、エラーEWOULDBLOCKが返されます。その後

unsigned long non_blocking = 1; 
ioctlsocket (sockClient, FIONBIO, &non_blocking); 

読みは

bytesRcvd = recv(sockClient, buffer, RCVBUFSIZE - 1, 0); 
if (bytesRcvd == -1) { 
    if (WSAGetLastError() == EWOULDBLOCK) { 
     // nothing to read now 
    } else { 
     // an actual error occurred 
    } 
} else { 
    // reading was successful. Call to MsgBox here 
} 

(2B)または、あなたが実際にreadを呼び出す前に、読むべきデータがあるかどうかを判断するためにselectを呼び出すことになります。

struct timeval timeout; 
timeout.tv_usec = 0; 
timeout.tv_sec = 0; 

fd_set r; 
FD_ZERO (&r); 
FD_SET (sockClient, &r); 
switch (select (sockClient + 1, &r, NULL, NULL, &timeout)) { 
    case -1: 
     // error 
     break; 
    case 0: 
     // nothing to read 
     break; 
    case 1: 
     // you may call read() 
     break; 
} 
+1

+1、良い答え。 recv()に 'MSG_PEEK'を渡して読み込み可能なバイトがあるかどうかを確認することもできます。 –

+0

もし私が(2b)と一緒に行くなら、スタック上の任意のサイズのバッファをあらかじめ割り当てるか宣言する必要はありません。 FIONBIOでソケットを非ブロックとしてマークする価値はまだありますか? – cnd

+0

マルチスレッド化されていない(*と*が深刻なバグを持っている)場合、 'FIONBIO 'を設定するかどうかは' select'ベースの多重化を使用するときに違いはありません。 – dennycrane

関連する問題