简体   繁体   English

Java中的UDP线程无限循环

[英]UDP threading infinite loop in Java

I've written two programs.我写了两个程序。 Now each program uses threading to send and receive packets at the same time.现在每个程序都使用线程同时发送和接收数据包。 Whenever I send packets from the server to the client, the message at the client ends gets received in an infinite loop.每当我从服务器向客户端发送数据包时,客户端端的消息都会在无限循环中接收。 Ie; IE; I've added a print statement that prints the message sent and this goes forever in an infinite loop.我添加了一个打印语句来打印发送的消息,这将永远处于无限循环中。 I want to make it so that it receives the message, and then be able to write back to the server and exit whenever the user wants to.我想让它接收消息,然后能够写回服务器并在用户想要的时候退出。

I've tried using socket.close(), but this makes it so that the client receives the message and I can only write back to the server once.我试过使用 socket.close(),但这使得客户端接收到消息,我只能写回服务器一次。 After I send it, I can't send anymore.发了之后就不能发了I want to make it so that I can write back more than once.我想做到这一点,以便我可以多次回信。

Can anyone please point me in the right direction?谁能指出我正确的方向?

My code is as follows;我的代码如下;

public class UDPThreadClient extends Thread {

public static int port1;

//Create threaded server
UDPThreadClient (int port1) {
    System.out.println ("Starting threaded client");
    start();
}

public void run() {

    int port = port1;

    try {
        DatagramSocket serverSocket = new DatagramSocket(port1);
           byte[] receiveData = new byte[1024];
           byte[] sendData = new byte[1024];

           while (true) { 
                 DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                 serverSocket.receive(receivePacket);
                 String sentence = new String( receivePacket.getData());
                 SocketAddress address = receivePacket.getSocketAddress();


                 System.out.println("RECEIVED from " + address + " : " + 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);
                 //serverSocket.close();
           }  
    } catch (IOException e) {
        System.out.println (e.getMessage());
    }

}

//Create client
public static void main(String[] args) {

    int port = Integer.parseInt(args[0]);
    port1 = Integer.parseInt(args[1]);
    new UDPThreadClient (port1);
    try {

          BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));

          DatagramSocket clientSocket = new DatagramSocket();
          InetAddress IPAddress = InetAddress.getByName("localhost");

          byte[] sendData = new byte[1024];
          byte[] receiveData = new byte[1024];

          String sentence = inFromUser.readLine();

          sendData = sentence.getBytes();

          DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);

          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 (IOException e) {
        System.out.println (e.getMessage());
    }
}
   }

and

public class UDPThreadServer extends Thread {

public static int port1;

//Create threaded client
UDPThreadServer () {

    System.out.println ("Starting threaded server");
    start();


}

public void run() {

    try {
        DatagramSocket clientSocket = new DatagramSocket();

            BufferedReader inFromUser = new BufferedReader (new InputStreamReader(System.in));
            Scanner in = new Scanner (inFromUser);
            InetAddress IPAddress = InetAddress.getByName("localhost");
        byte[] sendData = new byte [1024];
        byte[] receiveData = new byte [1024];

        while (in.hasNextLine()) {
        String sentence = in.nextLine();
        //inFromUser.readLine();
        sendData = sentence.getBytes();

        DatagramPacket sendPacket = new DatagramPacket (sendData, sendData.length, IPAddress, port1);
        clientSocket.send(sendPacket);

        DatagramPacket receivePacket = new DatagramPacket (receiveData, receiveData.length);
        clientSocket.receive (receivePacket);

        String modSentence = new String (receivePacket.getData());
        System.out.println ("FROM SERVER: " + modSentence);
        }
        //clientSocket.close();
    } catch (IOException e) {
        System.out.println (e.getMessage());
    }

}

//Create server
public static void main(String[] args) {

    int port = Integer.parseInt(args[0]);
    port1 = Integer.parseInt(args[1]);
    new UDPThreadServer ();
    try {
        DatagramSocket serverSocket = new DatagramSocket (port);
        byte[] receiveData = new byte[1024];
        byte[] sendData = new byte[1024];

        while (true) {
            DatagramPacket receivePacket = new DatagramPacket (receiveData, receiveData.length);
            serverSocket.receive(receivePacket);
            String sentence = new String(receivePacket.getData());
            SocketAddress address = receivePacket.getSocketAddress();
            System.out.println ("Received from " + address + " : " + sentence);

            InetAddress IPAddress = receivePacket.getAddress();
            String capSentence = sentence.toUpperCase();
            sendData = capSentence.getBytes();
            DatagramPacket sendPacket = new DatagramPacket (sendData, sendData.length, IPAddress, port);
            serverSocket.send(sendPacket);
            //serverSocket.close();
        }

    } catch (IOException e) {
        System.out.println (e.getMessage());
    }
}

}

Thanks.谢谢。

Looking at UDPClientServer:查看 UDPClientServer:

When you create the Datagram packet, you give it the port to send it to, not the port that you are sending it from.当你创建数据报包时,你给它发送它的端口,而不是你发送它的端口。

When I ran your code, nothing happened.当我运行你的代码时,什么也没发生。 The server is waiting on port port , while the client sends to port port1 .服务器在端口port上等待,而客户端发送到端口port1 If you instead send to port port (not accessible from the main method, but changing it to a field instead of local method would fix that, then the infinite looping occurs because the server sends a packet to the same port it is listening on. There's your problem. Do you supply the same numbers as the first and second arguments to your program?如果您改为发送到端口port (无法从主方法访问,但将其更改为字段而不是本地方法将解决该问题,则发生无限循环,因为服务器将数据包发送到它正在侦听的同一端口。有您的问题。您是否向您的程序提供与第一个和第二个 arguments 相同的数字?

From the server, you can use receivePacket.getPort() to get the port where the packet came from.从服务器,您可以使用receivePacket.getPort()获取数据包的来源端口。

EDIT:编辑:

Your two classes have much repetition, which is probably a source of confusion.你的两个类有很多重复,这可能是混淆的根源。 One class has a main which starts a client then creates a server type loop tester.一个 class 有一个 main,它启动一个客户端,然后创建一个服务器类型的循环测试器。 The other class sets up a Server then creates a client type tester.另一个 class 设置一个服务器然后创建一个客户端类型测试器。

Below is only the class you've named UDPThreadServer with comments showing changes to make the server 'work' with the testing code in the main method.以下仅是您命名为 UDPThreadServer 的 class 注释,其中显示更改以使服务器与 main 方法中的测试代码一起“工作”。 Note that the server should send to a port that it is not listening to.请注意,服务器应发送到它未侦听的端口。 You are also reading port values from command line arguments.您还从命令行 arguments 读取端口值。 I just made up some numbers for the ports and stuck them in as constants.我只是为端口编了一些数字并将它们作为常量插入。

public class UDPThreadServer extends Thread
{

  public static int port1;

  UDPThreadServer()
  {
    //server or client?  it's hard to say.  you call the socket a clientSocket.
    System.out.println("Starting threaded server");
    start();
  }

  public void run()
  {
    try
    {
      // Here client(?) is set up with empty constructor.
      // It is a mystery what port it will get.
      DatagramSocket clientSocket = new DatagramSocket();

      BufferedReader inFromUser =
          new BufferedReader(new InputStreamReader(System.in));
      Scanner in = new Scanner(inFromUser);
      InetAddress IPAddress = InetAddress.getByName("localhost");
      byte[] sendData = new byte[1024];
      byte[] receiveData = new byte[1024];

      while (in.hasNextLine())
      {
        String sentence = in.nextLine();
        // inFromUser.readLine();
        sendData = sentence.getBytes();

        // sending to port1?  that must be the server.
        DatagramPacket sendPacket =
            new DatagramPacket(sendData, sendData.length, IPAddress, port1);
        clientSocket.send(sendPacket);

        DatagramPacket receivePacket =
            new DatagramPacket(receiveData, receiveData.length);
        clientSocket.receive(receivePacket);

        String modSentence = new String(receivePacket.getData());
        System.out.println("FROM SERVER: " + modSentence);
      }
      // clientSocket.close();
    } catch (IOException e)
    {
      System.out.println(e.getMessage());
    }
  }

  // Create server
  public static void main(String[] args)
  {

    // int port = Integer.parseInt(args[0]);
    int port = 1927; // or whatever
    // port1 = Integer.parseInt(args[1]);
    port1 = 1928;
    new UDPThreadServer();
    try
    {
      // server resides on port1?  if client sends to port 1, then this is so.
      DatagramSocket serverSocket = new DatagramSocket(port1);
      byte[] receiveData = new byte[1024];
      byte[] sendData = new byte[1024];

      while (true)
      {
        DatagramPacket receivePacket =
            new DatagramPacket(receiveData, receiveData.length);
        serverSocket.receive(receivePacket);
        String sentence = new String(receivePacket.getData());
        SocketAddress address = receivePacket.getSocketAddress();
        System.out.println("Received from " + address + " : " + sentence);

        InetAddress IPAddress = receivePacket.getAddress();
        String capSentence = sentence.toUpperCase();
        sendData = capSentence.getBytes();

        // where did you get the info from?  Client is set up with an empty constructor, so it is a mystery.
        port = receivePacket.getPort();

        DatagramPacket sendPacket =
            new DatagramPacket(sendData, sendData.length, IPAddress, port);
        serverSocket.send(sendPacket);
        // serverSocket.close();
      }

    } catch (IOException e)
    {
      System.out.println(e.getMessage());
    }
  }
}

Don't close the socket.不要关闭套接字。

If that doesn't answer your question you need to clarify it.如果这不能回答你的问题,你需要澄清它。

while(true) is an infinite loop. while(true)是一个无限循环。 Do you quit it in any case?在任何情况下你都会放弃它吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM