如何在Java中连续接收DatagramPackets

时间:2017-10-15 23:04:22

标签: java udp chat packet datagram

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

关于我如何解决这个问题的任何想法?

我是线程的新手,并不完全确定它们是如何工作的,但我想的可能是一个线程?

客户端:

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

1 个答案:

答案 0 :(得分:0)

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

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

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