0

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

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

UDP客户端:

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);
      }

   }
}

UDP服务器:

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

4 回答 4

1

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

于 2012-10-17T07:35:15.590 回答
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);
      }

   }
}
于 2012-10-17T07:43:12.123 回答
0

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

于 2012-10-17T09:33:03.247 回答
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

一个可行的解决方案是让客户端是多线程的。一个线程将负责发送请求,而另一个线程将负责接收传入的响应。这是一个骇人听闻的解决方案:

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();
   }

}
于 2012-10-17T18:32:03.657 回答