Question

I want to send data from one client to another client through the server using DatagramSocket class. The server receives data from the clients , add the clients port number and names in an array list , but does not send the data to destination client. How can I make the server listens to the data sent from the server ?? not just receive the data when press any button. the server contains "while loop" to listen to clients ,how can I do this in the client side?

client class:

 public class DatagramClient extends JFrame {

private JTextField jtf = new JTextField();
private JTextArea jta = new JTextArea();
private DatagramSocket socket;
private byte[] buf = new byte[256];

private InetAddress address;
private DatagramPacket sendPacket;
private DatagramPacket receivePacket;

public static void main(String[] args) {
new DatagramClient();
}
public DatagramClient() {

//GUI 

jtf.addActionListener(new ButtonListener()); // Register listener

try {

socket = new DatagramSocket();
address = InetAddress.getByName("localhost");
sendPacket =
  new DatagramPacket(buf, buf.length, address, 8000);

receivePacket = new DatagramPacket(buf, buf.length);
}
 catch (IOException ex) {
  ex.printStackTrace();
 }
} 

private class ButtonListener implements ActionListener {
   public void actionPerformed(ActionEvent e) {
  try {

  Arrays.fill(buf, (byte)0);
  sendPacket.setData(jtf.getText().trim().getBytes());
  socket.send(sendPacket);
  socket.receive(receivePacket);

  jta.append("Radius is " + jtf.getText().trim() + "\n");
  jta.append("Area received from the server is "
    + Double.parseDouble(new String(buf).trim()) + '\n');
 }
catch (IOException ex) {
  ex.printStackTrace();
  }
 }
 }
}

server class:

public class DatagramServer extends JFrame {

private JTextArea jta = new JTextArea();
private byte[] buf = new byte[256];
ArrayList<Integer> clientPort=new ArrayList<Integer>();
ArrayList<String> clientName=new ArrayList<String>();


public static void main(String[] args) {
new DatagramServer();
}

public DatagramServer() {

//GUI
try {
DatagramSocket socket = new DatagramSocket(8000);
jta.append("Server started at " + new Date() + '\n');

DatagramPacket receivePacket =
new DatagramPacket(buf, buf.length);

DatagramPacket sendPacket ;

while (true) {


clientPort.add(receivePacket.getPort);
clientName.add( receivePacket.getAddress().getHostAddress());
Arrays.fill(buf, (byte)0);

socket.receive(receivePacket);
jta.append("The client host name is "+receivePacket.getAddress().getHostAddress() +
  " and port number is " + receivePacket.getPort() + '\n');

jta.append("Radius received from client is " +
  new String(buf).trim() + '\n');

double radius = Double.parseDouble(new String(buf).trim());
double area = radius * radius * Math.PI;
jta.append("Area is " + area + '\n');

  InetAddress addr=InetAddress.getByName(clientName.get(0));
  sendPacket = new DatagramPacket(buf, buf.length);

sendPacket.setAddress(addr);
sendPacket.setAddress(clientPort.get(0));

sendPacket.setData(new Double(area).toString().getBytes());
socket.send(sendPacket);
}
}
catch(IOException ex) {
 ex.printStackTrace();
}
} 
Was it helpful?

Solution

The easiest way would be to start a new thread that can run the client network loop.

Create a class that implements 'Runnnable' and then create a new Thread to run that class. That class's 'run()' method should loop and receive messages.

DatagramSocket is thread-safe, so you don't need to worry about accessing it from two separate threads (writing from the GUI thread, reading from the receiving thread).

However, the JTextArea and other GUI components are different. They can only be modified from the GUI thread. So you can't append to the 'JTextArea' from the receiver thread.

The easiest way to pass data to the GUI thread (from the receiver thread) would be like this.

SwingUtilities.invokeLater(new sendString(client, receivedMessage);

This requires a second new Runnable class sendString. The Runnable class's run() method can then perform the update, as invokeLater will cause it to be run by the GUI thread. client should be a reference to your DatagramClient instance.

client.jta.append(receivedMessage);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top