2012-04-25 1 views
6

シンプレックス(片道送信)またはデュプレックスモード(双方向)で動作できるリンクを介して、送信者から受信者にデータをポイントツーポイントで送信するアプリケーションがあります。シンプレックスモードでは、アプリケーションはUDPを使用してデータを送信し、デュプレックスではTCPを使用します。 TCPソケット上の書き込みがブロックされる可能性があるため、Non Blocking IO(FIONBIO-O_NONBLOCKのioctlとfcntlはこのディストリビューションではサポートされていません)とselect()システムコールを使用して、データを書き込めるかどうかを判断します。 NIOは、ネットワーク状態が悪化した場合に、必要に応じてタイムアウト後に早めに送信を中止できるようにするために使用されます。同じ基本コードを使用して送信を行いたいが、より高い抽象度でTCP/UDPを変更する。これはTCPに最適です。非ブロッキングUDP書き込みは、要求されたバイト数より少ないバイト数で返すことができますか?

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

私はかなりソケットプログラミングの新しいですので、ここでいくつかの誤解がある場合は私を許してください。ありがとうございました。

+0

おそらく、作業しているシステムの詳細を確認する必要があります。 UDPスタックには特定の制限があるかもしれません(実際には、すでに述べたように)。 – geekosaur

答えて

2

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

UDPメッセージ全体を送信できない場合は、EMSGSIZEエラーが発生します。送信されたメッセージは、ネットワークのある時点でサイズが原因で失敗する可能性があります。この場合、メッセージが届かない場合があります。しかし、IPスタックがひどくバグでない限り、それは断片的には配信されません。

大まかには、UDPペイロードサイズを最大1400バイトに保つことです。これは非常におおよそのもので、断片化を避けるために様々な形のトンネリングのための余地がたくさんあります。

+0

ありがとうございます。私はさらにいくつかのテストを行い、ペイロード全体かUDPのどれかがUDPを使ってwrite()を呼び出すために送られないことを発見しました。これは本当に唯一の論理的なものです。私はVxWorks 5.5で、ベンダーがTOEをサポートするスタックを提供しています...ターゲットプラットフォームでEMSGSIZEが表示されないことに驚くことはありません。とにかく、権威のある応答のおかげで、それは間違いなく私がベースをカバーしたという確信を提供するのに役立ちます。 – aig7761