22

クライアントからサーバーに UDP パケットを送信するプログラムを作成しました。

送信機のコードは次のとおりです。

import java.io.IOException;
import java.net.*;

public class JavaApplication9 {    
    public static void main(String[] args) throws UnknownHostException, SocketException, IOException  {
        // TODO code application logic here
        byte[] buffer = {10,23,12,31,43,32,24};
        byte [] IP = {-64,-88,1,106};
        InetAddress address = InetAddress.getByAddress(IP);
        DatagramPacket packet = new DatagramPacket(
                buffer, buffer.length, address, 57
                );
        DatagramSocket datagramSocket = new DatagramSocket();
        datagramSocket.send(packet);
        System.out.println(InetAddress.getLocalHost().getHostAddress());
    }
}

レシーバーコード関数は次のとおりです。

public void run() {
    try {
        DatagramSocket serverSocket = new DatagramSocket(port);
        byte[] receiveData = new byte[8];
        byte[] sendData = new byte[8];

        while (true) {
              DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
              serverSocket.receive(receivePacket);
              String sentence = new String( receivePacket.getData());
              System.out.println("RECEIVED: " + sentence);
              InetAddress IPAddress = receivePacket.getAddress();
              String sendString = "polo";
              sendData = sendString.getBytes();
              DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
              serverSocket.send(sendPacket);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Wireshark プログラムを使用しました。UDP パケットは受信側の Wireshark プログラムで受信されますが、Java プログラムはそれを認識せず、プログラムはポートをリッスンし続け、何も起こりませんか?

4

1 に答える 1

36

受信者は、送信者の DatagramPacket で設定されたポートと一致するように、受信者のポートを設定する必要があります。デバッグの場合は、ポート > 1024 (5000 または 9000 など) でリッスンしてみてください。通常、1024 未満のポートはシステム サービスによって使用され、そのようなポートにバインドするには管理者アクセスが必要です。

受信側がリッスンしているハードコーディングされたポート (ポート 57 など) にパケットを送信し、送信側が同じマシン上にある場合、受信側自体へのループバックを作成します。パケットから指定されたポートを常に使用し、実稼働ソフトウェアの場合、そのような状況を防ぐためにチェックが必要になります。

パケットが宛先に届かないもう 1 つの理由は、送信者で指定された IP アドレスが間違っていることです。UDP は TCP とは異なり、アドレスに到達できない場合でもパケットの送信を試み、送信者はエラー表示を受信しません。これは、デバッグの予防措置として受信機のアドレスを出力することで確認できます。

設定した送信者で:

 byte [] IP= { (byte)192, (byte)168, 1, 106 };
 InetAddress address = InetAddress.getByAddress(IP);

ただし、アドレスを文字列形式で使用する方が簡単な場合があります。

 InetAddress address = InetAddress.getByName("192.168.1.106");

つまり、ターゲットを 192.168.1.106 に設定します。これが受信者でない場合、パケットは取得されません。

動作する単純な UDP レシーバーを次に示します。

import java.io.IOException;
import java.net.*;

public class Receiver {

    public static void main(String[] args) {
        int port = args.length == 0 ? 57 : Integer.parseInt(args[0]);
        new Receiver().run(port);
    }

    public void run(int port) {    
      try {
        DatagramSocket serverSocket = new DatagramSocket(port);
        byte[] receiveData = new byte[8];
        String sendString = "polo";
        byte[] sendData = sendString.getBytes("UTF-8");

        System.out.printf("Listening on udp:%s:%d%n",
                InetAddress.getLocalHost().getHostAddress(), port);     
        DatagramPacket receivePacket = new DatagramPacket(receiveData,
                           receiveData.length);

        while(true)
        {
              serverSocket.receive(receivePacket);
              String sentence = new String( receivePacket.getData(), 0,
                                 receivePacket.getLength() );
              System.out.println("RECEIVED: " + sentence);
              // now send acknowledgement packet back to sender     
              DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,
                   receivePacket.getAddress(), receivePacket.getPort());
              serverSocket.send(sendPacket);
        }
      } catch (IOException e) {
              System.out.println(e);
      }
      // should close serverSocket in finally block
    }
}
于 2012-12-08T18:41:12.913 に答える