【问题标题】:How to Continuously receive DatagramPackets in Java如何在 Java 中连续接收 DatagramPackets
【发布时间】:2018-03-27 10:00:50
【问题描述】:

我编写了一个当前处于无限循环中的客户端和服务器,允许一次发送和接收一条消息。我需要它能够连续发送/接收消息,而不是一次仅限于一个。

有什么想法可以解决这个问题吗?

我是线程的新手,不完全确定它们是如何工作的,但我想也许是线程?

客户:

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

public class ClientChat {

    DatagramSocket Socket;

    public ClientChat(){

    }

    public void createAndListenSocket() throws SocketException, IOException{

        while(true){
            Socket = new DatagramSocket();
            InetAddress IPAddress = InetAddress.getLocalHost();
            System.out.println("Type your message:");
            BufferedReader message = new BufferedReader(new InputStreamReader(System.in));
            byte[] incomingData = new byte[256];
            String sentence = message.readLine();//"Testing from client";
            byte[] data = sentence.getBytes();
            DatagramPacket sendPacket = new DatagramPacket(data, data.length, IPAddress, 9876);
            Socket.send(sendPacket);
            System.out.println("Client: " + sentence);
            DatagramPacket incomingPacket = new DatagramPacket(incomingData, incomingData.length);
            Socket.receive(incomingPacket);
            String reply = new String(incomingPacket.getData());
            System.out.println("Server: " + reply);
            //Socket.close();

        }

    }

    public static void main(String[] args) throws IOException{
        ClientChat client = new ClientChat();
        client.createAndListenSocket();
    }
}

服务器:

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

public class ServerClient {

    public void run() throws Exception{

        DatagramSocket Server = new DatagramSocket(9876);

        while(true){        
            byte[] buf = new byte[1024];   
            DatagramPacket incomingPacket = new DatagramPacket(buf, buf.length);
            Server.receive(incomingPacket);
            String message = new String(incomingPacket.getData());
            System.out.println("Client: " + message);
            System.out.print("Server: ");
            BufferedReader response = new BufferedReader(new InputStreamReader(System.in));
            String reply = response.readLine();
            InetAddress IPAddress = incomingPacket.getAddress();
            int port = incomingPacket.getPort();
            byte[] data = reply.getBytes();
            DatagramPacket replyPacket = new DatagramPacket(data, data.length, IPAddress, port);
            Server.send(replyPacket); 


        }
    }

    public static void main(String[] args) throws Exception {
        ServerClient Server = new ServerClient();
        Server.run();
    }        
}

【问题讨论】:

  • 您已经在这样做了。 DatagramSocket 应该在循环外创建。否则很难说出你实际在问什么。

标签: java udp chat packet datagram


【解决方案1】:

你是对的。您应该使用两个线程 - 一个用于发送,一个用于接收。您还需要两个缓冲区来存储等待发送或接收后处理的数据。最有可能的是,您需要 FIFO 缓冲区(一个简单的双向同步队列)。然后,您的主线程只能处理向队列读取/写入数据,发送/接收线程将在后台处理其余的工作。

  • 发送线程应尝试在循环中从发送队列中读取。队列上的读取操作应该阻塞(暂停线程)直到数据可用。
  • 接收线程应该循环运行以从网络读取数据报并将其存储到“已接收”队列中。从网络读取数据报会阻塞,而存储到队列中会立即返回,除非队列已满。
  • 程序完成后,您必须以某种方式将线程从循环中“中断”。例如,您可以在主线程中将“shouldExit”布尔值设置为 true,并在发送/接收线程中检查它。如果您不关心,您也可以将线程设置为守护程序模式或调用 System.exit()。

适当调整队列大小。如果太小,消息将丢失和/或线程将被阻塞很多时间。如果太大,就会浪费内存。例如,估计(或观察)队列中的平均和最大消息数,并添加安全边际。

【讨论】:

  • 非常感谢这个详细的回复绝对是我正在寻找的答案!我对线程并不熟悉,因为我刚刚真正开始在学校的编程领域工作,所以我将不得不研究它们以了解如何编写和实现它们,但我想一旦我明白你的回答给了我一个了解概念的好地方!
  • 补充问题。是否可以在循环上方声明 DatagramPacket incomingPacket = new DatagramPacket(buf, buf.length); 以便重用相同的 DatagramPacket 对象,而不是在每次迭代时创建一个新对象?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
  • 2018-02-17
  • 2021-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-23
相关资源
最近更新 更多