简体   繁体   English

有关Java UDP与多线程通信的问题

[英]A problem about Java UDP communication with multi thread

I'm studying java network programming now and i wrote a program that the client sends 30 times current time to Server and the Server will create a new thread to parse the received UDP packet and give feedback to Client if Server receives the UDP packet. 我现在正在研究Java网络编程,我编写了一个程序,客户端将当前时间发送给服务器30倍,服务器将创建一个新线程来解析接收到的UDP数据包,并在服务器收到UDP数据包时向客户端提供反馈。

The question is, after I run my code, the Server can receive the UDP packet and create a new thread, but it seems like DatagramSocket and DatagramPacket don't pass to the thread. 问题是,在运行代码之后,服务器可以接收UDP数据包并创建一个新线程,但是好像DatagramSocketDatagramPacket不会传递给该线程。 Thence the thread can't give a feedback to Client and Client will wait all the time after send the first UDP packet. 因此,线程无法向客户端提供反馈,因此客户端在发送第一个UDP数据包后将一直等待。

My code is here: 我的代码在这里:

Server 服务器

public class MulUDPServer {
public static void main(String[] args) {
    DatagramSocket socket = null; 
    DatagramPacket receivedPacket; 
    final int PORT = 10010; 
    byte[] b = new byte[1024];
    receivedPacket = new DatagramPacket(b, b.length);
    try {
        socket = new DatagramSocket(PORT);
        System.out.println("Server start!");
        while (true) {
            // receive the packet from server
            socket.receive(receivedPacket);
            // to check if Server get the packet
            System.out.println(new String(receivedPacket.getData(), 0, receivedPacket.getLength()));
            // start the thread to handle the packet we have got
            Thread thread = new Thread(new LogicThread(socket, receivedPacket));
            thread.start();
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            // close the connection
            socket.close();
        } catch (Exception e) {
        }
    }
}

Thread 线

public class LogicThread implements Runnable {

DatagramSocket socket = null;
DatagramPacket receivedPacket = null;

public LogicThread(DatagramSocket socket, DatagramPacket receivedPacket) {
    this.socket = socket;
    this.receivedPacket = receivedPacket;
}

public void run() {
    try {
        // to test if a thread have been set up
        System.out.println("a thread have been set up");
        byte[] data = receivedPacket.getData();
        int len = receivedPacket.getLength();
        // get the client IP
        InetAddress clientAddress = receivedPacket.getAddress();
        // get the client port
        int clientPort = receivedPacket.getPort();
        // print the info about received packet
        System.out.println("Client's IP:" + clientAddress.getHostAddress());
        System.out.println("Client's port:" + clientPort);
        System.out.println("The info:" + new String(data, 0, len));
        // feedback to Client
        byte[] b = "OK".getBytes();
        DatagramPacket sendPacket = new DatagramPacket(b, b.length, clientAddress, clientPort);
        // send
        socket.send(sendPacket);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

Client 客户

public class MulUDPClient {
public static void main(String[] args) {
        DatagramSocket socket = null; 
        DatagramPacket sendPacket; 
        DatagramPacket receivedPacket; 
        String serverHost = "localhost"; 
        int serverPort = 10010; 
        try {
            socket = new DatagramSocket();
            InetAddress address = InetAddress.getByName(serverHost);
            byte[] b = new byte[1024];
            receivedPacket = new DatagramPacket(b, b.length);
            System.out.println("Client ready!");
            for (int i = 0; i < 30; i++) {
                // get the current time
                Date d = new Date(); 
                String content = d.toString(); 
                byte[] data = content.getBytes();
                sendPacket = new DatagramPacket(data, data.length, address, serverPort);
                socket.send(sendPacket);
                System.out.println("already send time");
                Thread.sleep(10);

                // receive packet from Server
                socket.receive(receivedPacket);
                byte[] response = receivedPacket.getData();
                int len = receivedPacket.getLength();
                String s = new String(response, 0, len);
                System.out.println("the feedback from Server:" + s);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // close the connection
                socket.close();
            } catch (Exception e) {
            }
        }
    }
}

the **Result** after run the Server and Client separately in two terminals: 在两个终端分别运行服务器和客户端后的“结果”:

Server 服务器

Server start!
Fri Nov 23 14:52:02 CST 2018
a thread have been set up

Client 客户

Client ready!
already send time

From the result we can know, the Client have send a UDP packet and the Server parse it correctly and create a thread. 从结果我们可以知道,客户端已经发送了UDP数据包,服务器正确地解析了该数据包并创建了一个线程。 Then the program is waiting... 然后程序正在等待...

It puzzle me a few days, Can anyone help me to solve it? 几天让我感到困惑,有人可以帮我解决吗? :). :)。 Thanks! 谢谢!

Edit 编辑

Client 客户

**CAN NOT** work **不能**工作

for (int i = 0; i < 30; i++) {
    Thread writerWorker = new WriterWorker(socket);
    writerWorker.start();
    Thread readerWorker = new ReaderWorker(socket);
    readerWorker.start();
}

**CAN** work **能行得通

for (int i = 0; i < 30; i++) {
    Date d = new Date(); 
    String content = d.toString(); 
    byte[] data = content.getBytes();
    sendPacket = new DatagramPacket(data, data.length, address, serverPort);
    socket.send(sendPacket);
    Thread.sleep(10);
    Thread readerWorker = new ReaderWorker(socket);
    readerWorker.start();
}

WriterWorker WriterWorker

public class WriterWorker extends Thread {
    DatagramSocket socket;
    String serverHost = "localhost";
    int serverPort = 10000;
    DatagramPacket sendPacket;

    public WriterWorker(DatagramSocket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            InetAddress address = InetAddress.getByName(serverHost);
            Date d = new Date();
            String content = d.toString();
            byte[] data = content.getBytes();
            sendPacket = new DatagramPacket(data, data.length, address, serverPort);
            socket.send(sendPacket);
            System.out.println("already send time");

        } catch (Exception e) {
            // TODO: handle exception
        }
    }
}

there is a flaw in your logic, when you do socket.receive(receivedPacket); 当您执行socket.receive(receivedPacket);时,您的逻辑存在缺陷socket.receive(receivedPacket); this will let the worker wait until some datagramm packets does arrive... 这将使工作人员等到某些数据报文包到达之前...

the right way to handle asynchron communication via sockets would be the following (here an example for client side) 通过套接字处理异步通信的正确方法如下(这里是客户端的示例)

socket = new DatagramSocket();
Thread readerWorker = new ReaderWorker(socket);
readerWorker.start();

Thread writerWorker = new WriterWorker(socket);
writerWorker.start();

that way you would seperate reading and writing into different threads and the blocking methode socket.receive(...) would not stop your writing thread... 这样一来,您就可以将读写操作分开,而阻塞方法socket.receive(...)不会停止您的写入线程...

each worker would implement it's own worker loop 每个工作人员将实现自己的工作人员循环

writer loop: 编写器循环:

while(true){
    if (sendPacket!= null){
        socket.send(sendPacket);
    }
    Thread.sleep(10);
}

reader loop: 阅读器循环:

while(true){
    socket.receive(receivedPacket);
    handlePacket(receivedPacket);
}

NOTE: 注意:

that code was written totally out of my mind i didn't check proper syntax 该代码完全是出于我的想法而编写的,我没有检查正确的语法

删除客户端中的“ Thread.sleep(10)”

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

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