为什么我的简单UDPServer仅在首次运行时才接收来自UDPClient的数据包?

时间:2012-10-17 07:27:13

标签: java sockets udp

我的UDP客户端会不断发送“Hello Server!”每2秒到UDP服务器(谁只是回复消息但是大写)。他们都会打印他们收到的内容。

我的问题是我必须先运行服务器然后再运行客户端。如果我运行客户端然后服务器,服务器根本不会收到任何东西。我希望服务器在他想要的任何时间启动并仍然从客户端接收数据包。我怎么能这样做?

UDPClient:

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

class UDPClient
{
   public static void main(String args[]) throws Exception
   {
      while(true) {
         DatagramSocket clientSocket = new DatagramSocket();
         InetAddress IPAddress = InetAddress.getByName("localhost");
         byte[] sendData = new byte[100];
         byte[] receiveData = new byte[100];
         String sentence = "Hello Server!";
         sendData = sentence.getBytes();
         DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
         clientSocket.send(sendPacket);
         DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
         clientSocket.receive(receivePacket);
         String modifiedSentence = new String(receivePacket.getData());
         System.out.println("FROM SERVER:" + modifiedSentence);
         clientSocket.close();
         Thread.sleep(2000);
      }

   }
}

UDPServer:

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

class UDPServer
{
   public static void main(String args[]) throws Exception
      {
         DatagramSocket serverSocket = new DatagramSocket(9876);
            byte[] receiveData = new byte[100];
            byte[] sendData = new byte[100];
            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();
                  int port = receivePacket.getPort();
                  String capitalizedSentence = sentence.toUpperCase();
                  sendData = capitalizedSentence.getBytes();
                  DatagramPacket sendPacket =
                  new DatagramPacket(sendData, sendData.length, IPAddress, port);
                  serverSocket.send(sendPacket);
               }
      }
}

4 个答案:

答案 0 :(得分:1)

如果您首先运行客户端,当它尝试发送“Hello服务器!”时这是第一次,它会导致PortUnreachableException。因此,根本不会向服务器发送任何内容。将套接字代码包装在try / catch中并忽略异常条件。

答案 1 :(得分:1)

如果您首先运行客户端,它将获得异常PortUnreachableException并且客户端程序将关闭,为了不发生这种情况,您必须捕获异常,以便客户端继续运行。

尝试:

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

class UDPClient
{
   public static void main(String args[]) throws Exception
   {
      while(true) {
         try{
         DatagramSocket clientSocket = new DatagramSocket();
         InetAddress IPAddress = InetAddress.getByName("localhost");
         byte[] sendData = new byte[100];
         byte[] receiveData = new byte[100];
         String sentence = "Hello Server!";
         sendData = sentence.getBytes();
         DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
         clientSocket.send(sendPacket);
         DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
         clientSocket.receive(receivePacket);
         String modifiedSentence = new String(receivePacket.getData());
         System.out.println("FROM SERVER:" + modifiedSentence);
         clientSocket.close();
         }
         catch (PortUnreachableException pe)
         {
           System.out.println("COULDN'T CONNECT TO SERVER:" + pe.getMessage());
         }
         catch (Exception ex)
         {
           System.out.println("COULDN'T CONNECT TO SERVER:" + ex.getMessage());
         }
         Thread.sleep(2000);
      }

   }
}

答案 2 :(得分:0)

你做不到。如果您不首先运行服务器,则数据报将被放入位桶中。唯一的缓解是客户端首先调用connect(),在这种情况下,他可能会在 next 发送时获得PortUnreachableException,,告诉他没有人回家。

答案 3 :(得分:0)

好的,现在是早上我又看了一眼。实际上,没有例外被抛出。实际问题是,当您首先启动客户端时,它正在等待服务器响应。但是,它永远不会收到服务器的响应,因为服务器没有及时启动以接收请求。

     clientSocket.send(sendPacket); //send message which will not be received
     clientSocket.receive(receivePacket); //wait forever for a response to a request that was never heard

一个有效的解决方案是让客户端成为多线程。一个线程将负责发送请求,而另一个线程将负责接收传入的响应。这是一个hackish解决方案:

class UDPClient {
   public static void main(final String args[]) throws Exception {
      final InetAddress IPAddress = InetAddress.getByName("localhost");
      new Thread() {
         @Override
         public void run() {
            while (true) {
               DatagramSocket clientSocket = null;
               try {
                  clientSocket = new DatagramSocket();
                  byte[] sendData = new byte[100];
                  final String sentence = "Hello Server!";
                  sendData = sentence.getBytes();
                  final DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
                  clientSocket.send(sendPacket);
                  Thread.sleep(2000);
               } catch (final Exception e) {
                  e.printStackTrace();
               } finally {
                  clientSocket.close();
               }
            }
         }
      }.start();
      new Thread() {
         @Override
         public void run() {
            DatagramSocket clientSocket = null;
            try {
               clientSocket = new DatagramSocket();
            } catch (final SocketException e1) {
               e1.printStackTrace();
            }
            while (true) {
               try {
                  final byte[] receiveData = new byte[100];
                  final DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                  clientSocket.receive(receivePacket);
                  final String modifiedSentence = new String(receivePacket.getData());
                  System.out.println("FROM SERVER:" + modifiedSentence);
               } catch (final Exception e) {
                  e.printStackTrace();
               }
            }
         }
      }.start();
   }

}