12

send()送信されたバイト数またはエラーコードを返しますが、私が見つけたすべての例はエラーコードのみでチェックし、送信されたバイト数ではチェックしません。

//typical example
int cnt=send(s,query,strlen(query),0);
if (cnt < 0) return(NULL);
//Hey, what about cnt < strlen(query)?
4

3 に答える 3

13

Q: 「send()」は常にバッファ全体を返しますか?

A: いいえ、必ずしもそうではありません。

Beej のガイドから: * http://beej.us/guide/bgnet/html/multi/syscalls.html#sendrecv

send() は、実際に送信されたバイト数を返します。これは、送信するように指示した数よりも少ない場合があります! ほら、データの塊全体を送信するように指示しても、それを処理できない場合があります。可能な限り多くのデータを送信し、後で残りを送信することを信頼します. send() によって返された値が len の値と一致しない場合、残りの文字列を送信するのはあなた次第です。良いニュースは次のとおりです。パケットが小さい場合 (1K 程度未満)、おそらくすべてを一度に送信することができます。ここでも、エラーの場合は -1 が返され、errno にエラー番号が設定されます。

Q: "recv()" は常にバッファ全体を読み取りますか?

A: いいえ、絶対にありません。受信したバッファが「メッセージ全体」であると想定しないでください。または、受信したメッセージが1 つの 1のメッセージからのものであるとします。

ここに良い、短い説明があります。これは Microsoft/C# 用ですが、任意の言語のすべてのソケット I/O に適用できます。

于 2012-09-29T22:29:56.620 に答える
4

答えはの別のセクションにありman 2 sendます:

   When the message does not fit into  the  send  buffer  of  the  socket,
   send()  normally blocks, unless the socket has been placed in nonblock‐
   ing I/O mode.  In nonblocking mode it would fail with the error  EAGAIN
   or  EWOULDBLOCK in this case.  The select(2) call may be used to deter‐
   mine when it is possible to send more data.

または、POSIX バージョン ( man 3p send):

   If  space is not available at the sending socket to hold the message to
   be transmitted, and the socket file descriptor does not have O_NONBLOCK
   set,  send()  shall  block  until  space is available.  If space is not
   available at the sending socket to hold the message to be  transmitted,
   and  the  socket file descriptor does have O_NONBLOCK set, send() shall
   fail. The select() and poll() functions can be used to  determine  when
   it is possible to send more data.

したがって、read部分的なデータの a は一般的ですがsend、ブロック モードでの部分的なデータは発生しないはずです (実装の詳細を除いて)。

于 2012-09-29T22:32:22.350 に答える
3

いいえ、そうではありません。

参考までに、send の man ページを参照してください。

メッセージがソケットの送信バッファーに収まらない場合、send() は、ソケットが非ブロッキング I/O モードに設定されていない限り、通常はブロックされます。非ブロッキング モードでは、この場合、エラー EAGAIN または EWOULDBLOCK で失敗します。select(2) 呼び出しを使用して、追加のデータをいつ送信できるかを判断できます。

于 2012-09-29T22:30:06.520 に答える