2017-04-21 6 views
0

私はクライアントを使ってサーバーに書き込みます。私は、ソケットが私のクライアントに書き込むためにオープンされているかどうかを調べ、接続が確立されてから10秒後に準備が整っていなければ、タイムアウトのためにエラーメッセージを表示してクライアントを終了したい。send()を使用する前にselect()でソケットをチェックしてください

クライアントはsend関数だけで正常に動作し、クライアントからサーバーにファイルを転送できます。しかし、select()機能を実装すると、クライアントはsel_valueを0に設定してタイムアウトします。

読みやすくするために、私は送信機能を実行するコードを削除しました。物をバッファに読み込むための追加ロジック。

//set up select for sending 
fd_set wfds; 
struct timeval timeout; 
while (1) { 
    FD_ZERO(&wfds); 
    FD_SET(sockfd, &wfds); 

    timeout.tv_sec = 10; 
    timeout.tv_usec = 0; //no us 

    int sel_value = select(sockfd+1, &wfds, NULL, NULL, &timeout); 
    cout<<"sel_value is: "<<sel_value<<endl; 
    if(sel_value == -1){ 
     perror("select"); 

    }else if(sel_value == 0){ 
     printf("Timeout. Cannot send for 10s \n"); 
     break; 
    } 
    else{ 
     if(FD_ISSET(sockfd, &wfds)){ 
      //my code never reaches this point, but here is where we send 
      //code to send stuff 
     } 
    } 

} 

答えて

0

これを前から次にしています。あなたはsendを実行するだけで、sendがEAGAIN/EWOULDBLOCKを受け取った場合は書き込み可能にする必要があります。ソケットの送信バッファがいっぱいの場合を除いて、ほとんどの場合、ソケットは書き込み準備が整います。システムコールを2倍にしてレイテンシを追加するあなたのやり方。

+0

私は少し混乱しています。私がsendを実行した場合、errno = EAGAIN |であるかどうかを確認する必要があります。 errno = EWOULDBLOCK。 errnoがこれらの値のいずれかである場合、再送を試みますか? select()を呼び出して戻り値を読み取ることでこれを行う方法が1つあります:書き込む準備ができたら、continue()を実行してループ内のsendに戻ることができますか? – jonnyd42

+0

私はそれに答えました。 'errno'がEAGAIN/EWOULDBLOCKの場合、を選択します。 – EJP

+0

ソケットがブロックしていても何を言っているのですか? – jonnyd42

関連する問題