2012-05-11 77 views
16

我已经做了计划,从客户这里发送一个UDP数据包到服务器发送源代码使用Java发送和接收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程序无法识别它,程序只是继续监听端口,什么也没有发生?

+0

确定服务器正在监听的正确的端口? – elias

+0

除非'address'是正确的并且'port'是57,否则这段代码将在第一个receive()调用中被阻塞。 – EJP

+3

不要将IP地址表示为负数。这很荒谬。写出实际的八位字节值并使用强制转换。 – EJP

回答

28

接收方必须设置接收方的端口以匹配发送方DatagramPacket中设置的端口。对于调试,尝试侦听端口> 1024(例如8000或9000)。端口< 1024通常由系统服务使用,并且需要管理员访问才能在此端口上进行绑定。

如果接收方将数据包发送到正在监听的硬编码端口(例如端口57),并且发送方位于同一台机器上,那么您将为接收方本身创建一个环回。请始终使用数据包中指定的端口,并且在任何情况下生产软件都需要检查以防止出现此类情况。

数据包无法到达目的地的另一个原因是发件人指定的IP地址错误。与TCP不同,UDP将尝试发送一个数据包,即使该地址不可达,发送者也不会收到错误指示。您可以通过在接收机中打印地址来进行检查,以作为调试的预防措施。

在发件人设置:

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]; 

     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(); 
       String sendString = "polo"; 
       byte[] sendData = sendString.getBytes("UTF-8"); 
       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 
    } 
} 
+0

执行此操作的简单方法是重新使用请求数据报作为响应,因为它已经有对等地址:端口。只需重置数据。如果地址错误并且套接字已连接,发件人的确会收到错误。 – EJP