2012-09-29 7 views
9

send()は送信されたバイト数またはエラーコードを返しますが、見つかったすべての例では、エラーコードのみでチェックしますが、送信バイト数ではチェックしません。send()は常にバッファ全体を送信しますか?

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

答えて

13

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

A:いいえ、必ずしもそうではありません。 Beejのガイドから

:* http://beej.us/guide/bgnet/output/html/multipage/syscalls.html#sendrecv

センド()が実際にアウト、この送信されたバイト数は、あなたが送信するためにそれを告げた数より 少ないかもしれません返します!参照してください、時々あなたは データ全体のゴブを送信するように指示し、それを処理することはできません。できるだけ多くのデータを消して残りの部分を に送信することを頼みます。 send()で返された値がlenの の値と一致しない場合、残りの文字列を送信するかどうかはあなた次第です。良い のニュースはこれです:パケットが小さい(1Kかそれ以下)場合 はおそらくすべてを一度に送ることを管理します。再び、-1はエラー時に が返され、errnoにエラー番号が設定されます。

Q:「recv()」は常にバッファ全体を読み込みますか?

A:いいえ、絶対にありません。 決してあなたが受け取ったバッファが "全体のメッセージ"であると仮定します。または、受信したメッセージがのいずれかであるとします。,メッセージです。

ここには簡単な説明があります。これは、Microsoft/C#のためだが、それはすべてのソケットI/O に適用だ、に任意の言語:

+5

-1:すべてのストリームベースのプロトコル(TCPなど)では、ローカルバッファが前回の送信からほぼ一杯になった場合、要求された量よりも少ないデータが返されることがあります。 UDPなどのデータグラムプロトコルの場合、送信は失敗したり、バッファ全体をパケットとして送信します(部分送信は不可能です)。 –

+1

私はダウン投票しませんでしたが、私の答えを見て、あなたは間違っています。 –

+0

@Kiril Kirov - あなたとクリスドッドは絶対に正しいと思う。私の部分の脳のおなら - 謝罪。私は私の答えを訂正しました。ありがとうございました! – paulsm4

3

いや、それはしていません。

参考のため、the man page for sendを参照してくださいメッセージがソケットの送信バッファに収まらない場合、ソケットがI/Oモードをノンブロッキングに置かれていない限り

は、() 通常ブロックを送ります。 ノンブロッキングモードでは、 の場合、EAGAINまたはEWOULDBLOCKエラーで失敗します。 select(2)呼び出しを使用して、いつより多くのデータを に送信できるかを判断できます。

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が一般的であるが答えはman 2 sendの別のセクションにある

+0

マニュアルページは混乱します。コメントはSOCK_STREAMソケットには適用されず、他のタイプにのみ適用されます。 –

4

ブロッキングモードの部分sendは発生しません(実装の詳細は除きます)。

+0

マニュアルページは混乱しています。コメントはSOCK_STREAMソケットには適用されず、他のタイプにのみ適用されます –

+0

機能のPosix定義の別の部分があります - 「メッセージが長すぎて下位のプロトコルを通過できない場合、 )は失敗し、データは送信されません "。なぜなら、あなたはUDPで部分的な送信を得ないからです。 –

関連する問題