7

recv を待機し、データを受信した後、処理のためにデータを転送するソケットがあります。しかし、その後再び recv に行き、今度は何も受信せずに -1 を返し、errno を出力すると 35 (つまりEAGAIN) を出力します。

これは MAC OS Lion オペレーティング システムでのみ発生し、他の OS では問題なく動作します。

do{
 rc = recv(i, buffer, sizeof(buffer), 0);
 if (rc < 0){
      printf("err code %d", errno); 
 }
 if(rc == 0){ 
      //Code for processing the data in buffer 
      break; 
 } 
      ....
}while(1);

編集: インデントとエラー番号を修正

4

2 に答える 2

7

ソケットを非ブロッキング モードに設定したか、受信タイムアウトを有効にしました。recv(2)これはMacからのものです:

次の場合、呼び出しは失敗します。

[EAGAIN]ソケットが非ブロッキングとマークされており、受信操作がブロックされるか、受信タイムアウトが設定されていて、データが受信される前にタイムアウトになりました。

編集 0:

うーん、また引用してすみません。今回はintro(2):

11 EDEADLKリソースのデッドロックが回避されました。デッドロック状態になるシステム リソースをロックしようとしました。

...

35 EAGAINリソースが一時的に利用できません。これは一時的な状態であり、後で同じルーチンを呼び出すと正常に完了する場合があります。

strerror(3)実際の問題を把握するために使用してください。

于 2013-01-30T02:39:33.393 に答える
3

ソケットはノンブロッキング モードです。読み取り可能なデータがない場合の (および他のシステム コール)EAGAINからの通常の戻り値です。recv()その意味では、それは実際にはエラーではありません。

ソケットがノンブロッキングであることを意図している場合は、ソケットを監視して、データが利用可能になったときを確認し、データが利用可能になったときにのみ呼び出す必要recv()があります。poll()(または FreeBSD と MacOS に固有の kqueue) を使用して監視します。通常、これはアプリケーションのメイン イベント ループで行われます。

ソケットをノンブロッキングにするつもりがなかった場合は、次のようにして、よりブロッキングに設定する必要がありfcntl()ます。

flags = fcntl(i, F_GETFL, 0); /* add error checking here, please */
flags &= ~O_NONBLOCK;
fcntl(i, F_SETFL, flags); /* add more error checking here! */

ただし、ソケット (およびすべてのファイル記述子) のデフォルトのブロック状態はブロッキングであることを認識しておく必要があります。そのため、ソケットが非ブロック モードの場合、誰かまたは何かが手動で非ブロックにしたことを意味します。

ブロッキングモードでは、recv呼び出しはブロックされ、戻る代わりにさらなるデータを待ちますEAGAIN(またはEWOULDBLOCKこれは と同じですEAGAIN)。

于 2013-01-30T02:36:08.707 に答える