6

シンプレックス(一方向送信)またはデュプレックスモード(双方向)で動作できるリンクを介して、送信者から受信者にデータポイントツーポイントを送信するアプリケーションがあります。シンプレックスモードでは、アプリケーションはUDPを使用してデータを送信し、デュプレックスモードではTCPを使用します。TCPソケットへの書き込みがブロックされる可能性があるため、ノンブロッキングIO(FIONBIOを使用したioctl-O_NONBLOCKおよびfcntlはこのディストリビューションではサポートされていません)とselect()システムコールを使用して、データを書き込むことができるタイミングを決定します。NIOは、ネットワークの状態が悪化した場合に必要に応じて、タイムアウト後早期に送信を中止できるようにするために使用されます。同じ基本コードを使用して送信を行いたいのですが、代わりに、より高い抽象化でTCP/UDPを切り替えます。これはTCPに最適です。

ただし、UDPソケットでノンブロッキングIOがどのように機能するかについて心配しています。マニュアルページを間違って読んでいる可能性がありますが、write()が返され、要求よりも送信されたバイト数が少ないことを示している可能性があるため、クライアントがデータグラムで受信するバイト数が少ないことを意味しますか?特定のデータバッファを送信するには、複数の書き込みが必要になる場合があります。これは、ノンブロッキングIOを使用しているためです。これが、クライアントが受信する複数のUDPデータグラムに変換されるのではないかと心配しています。

私はソケットプログラミングにかなり慣れていないので、ここで誤解がある場合はご容赦ください。ありがとうございました。

4

1 に答える 1

4

正しい(壊れていない)UDP実装を想定すると、各send / sendmsg / sendtoは送信された正確に1つのデータグラム全体に対応し、各recv / recvmsg/recvfromは受信された正確に1つのデータグラム全体に対応します。

UDPメッセージ全体を送信できない場合は、EMSGSIZEエラーが発生するはずです。送信されたメッセージは、ネットワークのある時点でサイズが原因で失敗する可能性があります。その場合、メッセージは単に到着しません。ただし、(IPスタックに深刻なバグがない限り)分割して配信されることはありません。

経験則として、UDPペイロードサイズを最大1400バイトに保つことです。これは非常に近似的であり、断片化を回避するためにさまざまな形式のトンネリングのための多くの余地を残します。

于 2012-04-26T22:13:09.880 に答える