Изпращане и получаване на UDP пакети?

Направих програма за изпращане на 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 не би го разпознала, програмата просто продължава да слуша порта и нищо не се случва?


person Amro Raed El Maadawi    schedule 11.05.2012    source източник
comment
Сигурни ли сте, че сървърът слуша правилния порт?   -  person elias    schedule 12.05.2012
comment
Освен ако address е правилен и port е 57, този код ще блокира при първото receive() извикване.   -  person user207421    schedule 12.05.2012
comment
Не представяйте IP адресите като отрицателни числа. Това е нелепо. Напишете действителните стойности на октетите и използвайте отливки.   -  person user207421    schedule 29.03.2015


Отговори (1)


Получателят трябва да настрои порта на получателя да съответства на порта, зададен в DatagramPacket на подателя. За отстраняване на грешки опитайте да слушате на порт › 1024 (напр. 8000 или 9000). Портове ‹ 1024 обикновено се използват от системни услуги и се нуждаят от администраторски достъп за свързване на такъв порт.

Ако приемникът изпрати пакет към твърдо кодирания порт, който слуша (напр. порт 57) и подателят е на същата машина, тогава ще създадете обратна връзка към самия приемник. Винаги използвайте порта, посочен от пакета, и в случай на производствен софтуер ще се нуждае от проверка във всеки случай, за да предотвратите такъв случай.

Друга причина пакетът да не стигне до местоназначението е грешният 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
    }
}
person JasonM1    schedule 08.12.2012
comment
Лесният начин да направите това е да използвате повторно дейтаграмата на заявката за отговора, тъй като тя вече съдържа peer address:port в нея. Просто нулирайте данните. Подателят наистина ще получи грешка, ако адресът е грешен и гнездото е свързано. - person user207421; 25.07.2014