web-dev-qa-db-ja.com

Javaを使用してUDPパケットを送受信しますか?

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

import Java.io.IOException;
import Java.net.*;

/**
 *
 * @author hp
 */
public class JavaApplication9 {

    /**
     * @param args the command line arguments
     */
    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 (Exception e){
    }
}

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

18

受信者は、送信者のDatagramPacketで設定されたポートと一致するように受信者のポートを設定する必要があります。デバッグのために、1024を超えるポート(たとえば、8000または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     
              InetAddress IPAddress = receivePacket.getAddress();
              DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,
                   IPAddress, receivePacket.getPort());
              serverSocket.send(sendPacket);
        }
      } catch (IOException e) {
              System.out.println(e);
      }
      // should close serverSocket in finally block
    }
}
30
JasonM1