2

LAN 内のすべてのコンピューターを DatagramSocket と DatagramPacket を介して自分のコンピューターに接続するプログラムを作成しています (つまり、私がサーバーになり、他のコンピューターがクライアントになります)。私はいくつかの調査を行い、ドキュメントを読み、それがどのように機能するかを知り、実際にネットワークを介してデータを送受信することができました. クライアントクラスのデータ送信メソッドには2つのオプションがあり、同等だと思っていましたが、そうではないようです。最初のもの (Client1):

DatagramSocket socket = null;
DatagramPacket packet = null;

try
{
     byte[] data= "test".getBytes();
     packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.0.26"), 325);
     socket = new DatagramSocket();
     socket.send(packet);
 }
 catch (Exception ex)
 {
     ...
 }

そして 2 つ目 (Client2):

DatagramSocket socket = null;
DatagramPacket packet = null;

try
{
     byte[] data= "test".getBytes();
     packet = new DatagramPacket(data, data.length);
     socket = new DatagramSocket(325, InetAddress.getByName("192.168.0.26"));
     socket.send(packet);
 }
 catch (Exception ex)
 {
     ...
 }

これら 2 つのオプションは、自分の PC との間でデータを送受信するテストを行っていたときに思いつきました。私の IP アドレスは 192.168.0.26 です。最初のものでは問題はありませんでしたが、2 番目のものでは 2 種類の例外がスローされます。Client1 が動作し、コンピューターで次のコードを同時に実行していることを確認できます。

(サーバ)

byte data[] = null;
try
{
    data= new byte[1000];
    socket = new DatagramSocket(325);
    packet = new DatagramPacket(datos, datos.length);
    socket.receive(packet);
    System.out.println(datos);
}
catch (Exception ex)
{
    ...
}

最初に Server を実行してから Client1 オプションを実行すると、実際にデータが受信されます。最初にClient1を実行してからサーバーを実行すると、明らかにデータは取得されませんが、例外も取得されません。本当の問題 (そして実際の質問、非常に多くの、おそらく役に立たない情報について申し訳ありません) は、Client2 にあります。これがサーバーの前に実行されると、NullPointerException が発生します。

java.lang.NullPointerException: null address || null buffer
at java.net.DualStackPlainDatagramSocketImpl.send(DualStackPlainDatagramSocketImpl.java:115)
at java.net.DatagramSocket.send(DatagramSocket.java:676)

メソッド send() が呼び出されたときに生成されます。これを無視する必要があるかもしれません。私はソケットの初心者だと思っていましたが、誰もデータを受信しないことがわかっている場合にデータを送信するのは間違っているようです。一方、Server が最初に実行され、次に Client2 が実行されると、BindException が発生します。

java.net.BindException: Address already in use: Cannot bind
at java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method)
at java.net.DualStackPlainDatagramSocketImpl.bind0(DualStackPlainDatagramSocketImpl.java:65)
at java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:95)
at java.net.DatagramSocket.bind(DatagramSocket.java:376)
at java.net.DatagramSocket.<init>(DatagramSocket.java:231)
at java.net.DatagramSocket.<init>(DatagramSocket.java:284)

ソケットが初期化されたときの行から。Client1 が機能するため、それを使用します。しかし、なぜそれが機能するのか知りたいのですが、Client2 は機能しません。ここの別のフォーラムでその BindException について読みましたが、既に使用されているポートを使用しようとしたときに発生したことを理解しましたが、この意味では Client1 も失敗するはずです。誰かが Client1 と Client2 の違いを説明してくれませんか?

4

1 に答える 1

2

同じポートにバインドしています。同じマシン/アドレスで実行している場合は、別のポートにバインドする必要があります。

サーバー上のように:

socket = new DatagramSocket(325);    //server binds its UDP/IP socket to port 325

クライアント 2:

socket = new DatagramSocket(325, InetAddress.getByName("192.168.0.26"));

「サーバー」が使用しているのと同じマシン/アドレスの同じポートにバインドしています

クライアント 1:

packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.0.26"), 325);
//you are specifying the destination address and port the packet should be sent.
socket = new DatagramSocket();
//but in the DatagramSocket contructor you don't pass any address or port to bind to, so it will use an available port, not 325 as it is in use by the server.

あなたがネットワーク通信に慣れていないと言ったように、これはUDP/IPソケットであり、TCP/IPなどがあることに注意してください。UDP/IP は仕様上接続指向ではなく、パケットが配信されることを保証しません。

于 2013-09-10T01:06:21.163 に答える