2016-01-27 14 views
7

1)API for send hereResult<usize>を返します。何故ですか ?私の頭の中では、UDPの送信はすべて、またはまったくありません。 RustのUDP API

let mut bytes_written = 0; 
while bytes_written < data.len() { 
    bytes_written += match udp_socket.send_to(&data[bytes_written..]) { 
     Ok(bytes_tx) => bytes_tx, 
     Err(_) => break, 
    } 
} 

最近誰かが私に言った、これは全く不要である:戻り値は、送信が成功することができますが、私はコードのようになりますどのデータ全体を書き込まれないことを示唆しているようです。しかし、私は理解していません。それが本当だったらなぜ返りは Result<()>でなく、それは私が期待していたものなのでしょうか?

2) For reads私は分かりますが。私はそれにサイズ100バイトのバッファを与えることができますが、データグラムは50バイトしかないかもしれません。だから本質的に私はread_buf[..size_read]だけを利用するべきです。ここで私の質問は、バッファサイズが100ですが、データグラムのサイズが150バイトだとどうなりますか? recv_fromは100バイトしか記入せず、Ok(100, some_peer_addr)を返しますか?私はそれがデータグラムの残りの部分を埋めるでしょうか? 2回目の読み込みの前に50バイトの別のデータグラムが到着した場合はどうなりますか?私は残りの50バイトを2回目に取得し、50バイトの新しいデータグラムを3回目に取得するか、100バイト目に2回目の新しいデータグラムが含まれていますか?またはエラーが発生し、私は最初の読み取りで最初のデータグラムを失い、それを回復することはできませんか?

答えて

9

これらの質問の両方への答えは、それぞれのBSDソケット機能、sendto()recvfrom()のドキュメントです。 * nixシステム(OS XやLinuxなど)を使用している場合は、man sendtoman recvfromを使用して見つけることができます。

1)sendto()マニュアルページはこれではあまり曖昧です。 Windows APIページでは、戻り値がlen引数未満である可能性が明示的に示されています。 thisの質問も参照してください。この特定の瞬間は、いくぶん実証されていないようです。戻り値は常にlenまたはエラーコードと等しいと仮定するのはおそらく安全だと思います。 sendto()によって送信されたデータの長さがOSカーネル内の内部バッファサイズを超えている場合に問題が発生する可能性がありますが、少なくともWindowsではこの場合エラーが返されるようです。

のrecvfrom()関数はに書き込まれたメッセージ の長さを返す:

2)recvfrom() manページを明確にバッファに収まらないデータグラムの一部が破棄されることを述べてbuffer引数がポイントするバッファ。 SOCK_RAW、SOCK_DGRAM、および SOCK_SEQPACKETのようなメッセージベースのソケット の場合、メッセージ全体が単一の オペレーションで読み取られます。メッセージが長すぎて指定されたバッファに収まらない場合、flags引数に とMSG_PEEKが設定されていない場合、超過バイトは になります。

そうです、recv_from()は正確に100バイトを記入します、残りは破棄され、recv_from()へのさらなる呼び出しは、新たなデータグラムを返します。

2

dig downの場合は、C sendto functionをラッピングするだけです。この関数は送られたバイト数を返すので、Rustはそれを単に渡します(-1の場合を処理し、errnoを実際のエラーに変換します)。