0

ソケットで無限ループを使用しています。データを受信した場合は受信するか、データを送信したい場合は送信します。以下のようなもの。セレクトを使用しています。私はソケットSDを1つしか持っていません。

fd_set readsd;
int maxsd = readsd +1;
// all those actions of setting maxsd to the maximum fd +1 and FDSETing the FDs.
while(1)
{
     FD_ZERO(&read_sd);
     FD_SET(sd, &read_sd);
     if(FD_ISSET(sd, &readsd))
     {
       //recv call
     }
     else
     {
       //send call
     }
}

私の知る限り、select は、データが最初に到着するソケット記述子の 1 つを選択します。しかし、ここではソケットが 1 つしかないため、データがある場合は受信したり、そうでない場合は送信したりします。

その場合、上記のコードは問題ありませんか?または、私が知らない他のオプションがありますか?

4

4 に答える 4

3

その場合、上記のコードは問題ありませんか?

選択する呼び出しが表示されません。また、「maxsd」が select の最初の引数になるように設計されている場合、その値は間違っています。最大のファイル記述子 +1 でなければなりません。とにかく、フラグ MSG_DONTWAIT を指定して recv を呼び出すだけで済みます。この場合、読み取るデータがない場合はエラーが返されます。

于 2013-05-15T12:32:01.193 に答える
2

あなたが何をしようとしているのかよくわからないので、2つのオプションについて考えることができます:

ソケットをノンブロッキングに設定する

ソケットが 1 つしかないように見えるので、ソケットをノンブロッキング モードに設定しfcntlて呼び出すことができます。recv()

fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK);
// if fcntl returns no error, sock is now non-blocking

セレクトタイマーをセットする

タイマーを使用selectすると、データが受信されなくても、しばらくすると強制的に復帰するように設定できます。

于 2013-05-15T12:35:10.953 に答える
2

それはちょっと依存します... まず第一に、実際のコードで実際に呼び出しがありますか?select

ブロッキングについて...selectソケットがリードセットに設定された状態で返された場合、ブロッキングrecvなしで呼び出すことができることが保証されます。ただし、利用可能なデータ量についての保証はありません。UDP を使用する場合、少なくとも 1 つの (できれば完全な) パケットが存在しますが、TCP を使用する場合は 1 バイトしか得られない場合があります。メッセージ境界のある一部のプロトコルでは、完全なメッセージを取得できない可能性があり、recvすべてのメッセージを取得するためにループで呼び出す必要があります。残念ながら、これにより遅かれ早かれrecv呼び出しがブロックされます。

要するに、使用selectすると役立ちますが、すべての場合に役立つわけではありません。呼び出しがブロックされないことを実際に保証する唯一の方法recvは、ソケットを非ブロックにすることです。

于 2013-05-15T12:27:53.430 に答える
0

selectまず、あなたのコードに何も見つかりません。

ただし、fcntl(fd, F_SETFL, flags | O_NONBLOCK)ソケットをノンブロッキングにするために最初に呼び出すことができます。次にerrno == EWOULDBLOCK、から何も読み取れないかどうかを確認しますrecv。この場合は使用する必要はありませんselect

于 2013-05-15T12:37:08.523 に答える