binke ou
binke ou

Reputation: 15

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.

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. Thence the thread can't give a feedback to Client and Client will wait all the time after send the first UDP packet.

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. 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

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

Upvotes: 1

Views: 1478

Answers (2)

Martin Frank
Martin Frank

Reputation: 3454

there is a flaw in your logic, when you do 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...

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

Upvotes: 2

wumin
wumin

Reputation: 1

delete the "Thread.sleep(10)" in client

Upvotes: 0

Related Questions