Androidで極端なUDP パケット損失が発生していますが、意味がありません。状況は次のとおりです。
- ホームネットワークに接続されたJavaクライアントを実行しているPC
- ホームネットワークに接続されたJavaサーバー(Android)を実行している電話
- ホームルーターは新品のWRT1900acです。ネットワークにはインターネット接続があります。
- UDP パケットが小さい (< 15 バイト)
症状:
PC が UDP パケットを別の PC (両方とも同じネットワーク上) に送信すると、非常にうまく機能します (ほとんどパケットが失われません)。
Android が UDP パケットを同じネットワーク上の PC に送信する場合も、非常にうまく機能します (パケットの損失はほとんどありません)。
PC が同じネットワーク上の Android に UDP を送信すると、極端なパケット損失が発生します (50% 以上の確率ですが、状況によって異なります)。
ほとんどの場合、パケットを 1 回通過させるのに 10 回ほどパケットを送信する必要があります。それ以外の場合は、かなりの遅延が発生します。Androidの受信側でのみ発生する非常に奇妙な動作。Android を Java で同じコードを実行する PCに置き換えるか、Packet Sender の UDP サーバーを介してパケットを受信するだけであれば、損失の問題はありません。私が気付いたもう 1 つのことは、ルーターを経由する代わりに、インターネットに接続されていない、または他のクライアントが存在しない別のアクセス ポイントを経由すると、パフォーマンスが劇的に向上するように見えることです。これは予想されることですが、私の質問は、なぜ Android の受信側のパフォーマンスがこれほど低いのかということです。非常に多くのパケットを失います。Android が、同じコードを実行し、同じネットワーク上で実行されている別の PC に置き換えられた場合、問題はありません。Android
また、パケットの送信に問題はありません(パケットが失われることはありません)。したがって、受信側でAndroidに関連する何かでなければなりません...
また、PC コードを Packet Sender に置き換えてみましたが、同じ結果が得られました。問題は Android の受信側にあるようです。PC側とAndroidで同じUDPコードを実行します。
UDP 送信コードは単純です。
public void sendMessage(String message)
{
try {
DatagramSocket ds = new DatagramSocket();
DatagramPacket dp;
InetAddress local = InetAddress.getByName(ipPool);
dp = new DatagramPacket(message.getBytes(), message.length(), local, port);
ds.setBroadcast(true);
ds.send(dp);
ds.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Android の UDP 受信コードは、UDP サーバー クラスに存在します。
public class UDP_Server
{
CommandParser commandParser;
public UDP_Server(MainActivity mainActivity)
{
Log.i("Udp tutorial", "---------------------------Starting UDP SERVER");
commandParser = new CommandParser(mainActivity);
String text;
int server_port = 9876;
try
{
DatagramSocket s = new DatagramSocket(server_port);
s.setBroadcast(true);
//s.setReceiveBufferSize(163840);
while (true)
{
byte[] message = new byte[1024];
DatagramPacket p = new DatagramPacket(message, message.length);
s.receive(p);
text = new String(message, 0, p.getLength());
Log.d("Udp tutorial","message:" + text);
//commandParser.parseCommand(text);
//s.close();
}
} catch (SocketException e)
{
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDPServer.java クラスは、メイン アクティビティの「onCreate()」メソッドによってインスタンス化されます。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
wm = (WifiManager) getSystemService(WIFI_SERVICE);
Log.i("Udp tutorial", "---------------------------HERE 1");
Thread thread = new Thread(new Runnable()
{
public void run()
{
UDP_Server svr = new UDP_Server(MainActivity.this);
}
});
thread.setPriority(Thread.MAX_PRIORITY);
thread.start();
// TCPServer server = new TCPServer();
}