7

man recv()システムに入力すると、次のようになります。

 ssize_t
 recv(int socket, void *buffer, size_t length, int flags);

 …

RETURN VALUES
 These calls return the number of bytes received, or -1 if an error occurred.

lengthは unsigned 型size_tであり、関数の結果は signed であることに注意してくださいssize_t

SSIZE_MAXforより大きい値が渡された場合、が指すメモリがいっぱいになり、以外の負の値を返すlength状況はどの程度理論的ですか? 非常に長いメッセージを許可するソケットのタイプはありますか (Unix ドメイン?)? どうですか?recv()buffer-1MSG_WAITALL

4

1 に答える 1

6

Posix 2008 の根拠が ssize_t について述べなければならないことは次のとおりです ( B.2.12 データ型から抽出)。

ssize_t
これは、size_t の符号付きアナログであることを意図しています。文言は、実装がより長い型を使用するか、単純に size_t の基になる型の符号付きバージョンを使用するかのいずれかを選択できるようなものです。ssize_t を返すすべての関数 (read() および write()) は、{SSIZE_MAX} を超える入力の結果を「実装定義」として記述します。

ssize_tを含むを返すソケット関数は、 をrecv超える入力について何も言及していないためSSIZE_MAXです。したがって、私はそれを意図の表明と見なしており、欠落している文言recvはエラーであり、いつか修正される可能性があることを暗示しています.

つまり、移植可能なコードを書きたい場合は、I/O セグメントが を超えないようにする必要がありますSSIZE_MAX。さらに、SSIZE_MAX32767 と小さい場合もあります。したがって、移植性の高いコードでは、それよりも大きい可能性があると想定すべきではありません。

ただし、誰もが移植性についてそれほど気にしているわけではありません。コードが実行される実装についてある程度知っているかもしれません。Posix は次のように続けます。

一部の実装では、size_t より小さい int を持つ可能性があることが認識されています。準拠するアプリケーションは、{SSIZE_MAX} よりも大きな部分で I/O を実行しないように制約されますが、拡張を使用する準拠するアプリケーションは、実装が拡張範囲を提供する場合、単一の型互換性を維持しながら、全範囲を使用できます。インターフェース。

Posix は、返される値recvが -1、0、または受信したバイト数だけであることを保証します。上記の表現によると、準拠する実装では、 より大きいSSIZE_MAXが以下の値を 以外2*SSIZE_MAXの負の整数にマッピングできます-1。(これがどのように達成されるかは、関心のある読者の演習として残されています:))。ただし、私の知る限り、Linux ではそのような拡張機能は文書化されていません。

于 2013-06-20T20:56:36.140 に答える