1

サーバーとして機能し、UDP パケットをリッスンする単純な Java プログラムがあります。次に、3g 経由で UDP パケットを送信するクライアントがあります。

私が気付いたのは、次のようなことが時折発生するように見えることです: 1 つのパケットを送信し、数秒後にまだ受信されていません。次に別のパケットを送信すると、突然両方が到着します。

サイズの小さいパケットを送信する代わりに、一定量のデータを待機する何らかのシステムが配置されている可能性があるかどうか疑問に思っていました. 私のアプリケーションでは、パケットごとに約 2 ~ 3 バイトのデータしか送信しませんが、UDP ヘッダーとそうでないものによってメッセージが少し大きくなります。

私のアプリケーションの目的は、これらの数バイトのデータを A から B にできるだけ速く取得することです。スピード重視。それはすべて偶然ですか?パケットサイズを大きくできると思いますが、転送時間が増えるだけのようで、3g は完全ではありません。

4

2 に答える 2

2

コメントがかなり長くなってきているので、それらをまとめて回答に変えたほうがよいかもしれません。

特定の量が取得されるまでアプリがデータを受信しない場合は、バックグラウンドで何らかのバッファリングが行われている可能性があります。良い例 (これがあなたに直接当てはまるとは言いません) は、あなたまたは基礎となるライブラリがInputStream.readLine()orを使用している場合、復帰する前に改行またはバイト数をInputStream.read(bytes)受け取るまでブロックすることです。bytes特定のしきい値に達すると、プログラムがすべてのデータを取得するように見えるという事実から判断すると、そのように思えます。

これをデバッグする良い方法は、Wireshark を使用することです。Wireshark はプログラムを気にしません。コンピュータとの間で送受信される未加工のパケットを分析し、問題が送信側にあるのか受信側にあるのかを教えてくれます。

Wireshark を使用していて、最初の送信からのデータが 2 番目の送信よりもかなり前に物理マシンに到着している場合、問題は受信側にあります。最初のパケットが 2 番目のパケットと同時に到着する場合、問題は送信者にあります。コードを見ないと、何をしているのか、具体的には何が原因でデータが 2 ~ 3 バイト以上受信された後にのみ表示されるのかを判断するのは困難です。 .

于 2012-05-13T05:26:15.747 に答える
1

There are several probable causes of this:

  1. Cellular data networks are not "always-on". Depending on the underlying technology, there can be a substantial delay between when a first packet is sent and when IP connectivity is actually established. This will be most noticeable after IP networking has been idle for some time.

  2. Your receiver may not be correctly checking the socket for readability. Regardless of what high-level APIs you may be using, underneath there needs to be a call to select() to check whether the socket is readable. When a datagram arrives, select() should unblock and signal that the socket descriptor is readable. Alternatively, but less efficiently, you could set the socket to non-blocking and poll it with a read. Polling wastes CPU time when there is no data and delays detection of arrival for up to the polling interval, but can be useful if for some reason you can't spare a thread to wait on select().

  3. I said above that select() should signal readability on a watched socket when data arrives, but this behavior can be modified by the socket's "Receive low-water mark". The default value is usually 1, meaning any data will signal readability. But if SO_RCVLOWAT is set higher (via setsockopt() or a higher-level equivalent), then readability will be not be signaled until more than the specified amount of data has arrived. You can check the value with getsockopt() or whatever API is equivalent in your environment.

Item 1 would cause the first datagram to actually be delayed, but only when the IP network has been idle for a while and not once it comes up active. Items 2 and 3 would only make it appear to your program that the first datagram was delayed: a packet sniffer at the receiver would show the first datagram arriving on time.

于 2012-05-14T15:54:22.433 に答える