0

こんにちは私はUDP接続でクライアントからのパケットを待機し、それらすべてが効果的に到着したか、またはそれらの同じものが拒否されたかどうかをチェックするプロキシサーバーを作成しています。

その場合、失われたパケットごとに(send_ack()を使用して)クライアントに「ack」を送信する必要がありますが、最初のackを送信した直後に、selectループの「ifpart」が無制限のackを送信して「else」に戻ることはありません。一部」は、クライアントからの選択されたリッスンデータでした(_pkt()関数を受信します)

fd_set rset, allset;
int maxfd, nready;
struct timeval timeout;

timeout.tv_sec = 4;
timeout.tv_usec = 150000; 
maxfd = socketfd;  
FD_ZERO(&allset);
FD_SET(socketfd, &allset);
rset = allset;

for( i=0; ;i++){
    do {
        nready=select( (maxfd +1), &rset, NULL, NULL,  &timeout); 
    } while ((nready<0) & (errno==EINTR)); 

    if( nready<0) {
        perror("Error main: select failed: ");
        exit(32);
    }  
    if( nready==0){ 
        send_ack(socketfd,head);
    }
    else{           
        receive_pkt(socketfd, head);
    }
}

アドバイスをありがとう、それが十分に明確であることを願っています!

4

2 に答える 2

2

一部のシステム (特に Linux) では、select呼び出しによってタイムアウトが変更され、残り時間が表示されます。したがって、あなたの場合、パケットを 3 秒間待機すると、タイムアウトは 1.15 秒に短縮され、合計 4.15 秒後にタイムアウトは 0 になるため、後で呼び出すselectとすぐに nready == 0 が返されます。

ACK の送信後に再度待機する場合は、タイムアウトをゼロ以外にリセットする必要があります。

于 2013-03-18T16:14:52.730 に答える
2

fd_set rsetを呼び出すたびに をリセットする必要がありselectます。呼び出しは、監視するフィールド記述子のselectビット セットを想定し、読み取る通知を含むフィールド記述子のビット セットで上書きします。

for( i=0; ;i++){
    do {
        rset = allset;
        nready=select( (maxfd +1), &rset, NULL, NULL,  &timeout); 
    } while ((nready<0) & (errno==EINTR)); 
于 2013-03-18T16:18:54.807 に答える