2

を使用して、サーバーを介してあるクライアントから別のクライアントにデータを送信したいと考えていますDatagramSocket class。サーバーはクライアントからデータを受信し、クライアントのポート番号と名前を配列リストに追加しますが、データを宛先クライアントに送信しません。サーバーから送信されたデータをサーバーにリッスンさせるにはどうすればよいですか?? ボタンを押したときにデータを受信するだけではありません。サーバーにはクライアントをリッスンするための「whileループ」が含まれていますが、クライアント側でこれを行うにはどうすればよいですか?

クライアントクラス:

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

サーバークラス:

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

1 に答える 1

1

最も簡単な方法は、クライアント ネットワーク ループを実行できる新しいスレッドを開始することです。

「Runnnable」を実装するクラスを作成し、そのクラスを実行する新しいスレッドを作成します。そのクラスの「run()」メソッドは、ループしてメッセージを受信する必要があります。

DatagramSocketはスレッドセーフなので、2 つの別々のスレッド (GUI スレッドからの書き込み、受信スレッドからの読み取り) からのアクセスについて心配する必要はありません。

ただし、JTextAreaと他の GUI コンポーネントは異なります。これらは、GUI スレッドからのみ変更できます。したがって、受信側スレッドから「JTextArea」に追加することはできません。

データを GUI スレッドに (レシーバー スレッドから) 渡す最も簡単な方法は、次のようになります。

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

これには、2 つ目の新しいRunnableクラスが必要sendStringです。その後、Runnableクラスのrun()メソッドが更新を実行できるようinvokeLaterになり、GUI スレッドによって更新が実行されます。 clientインスタンスへの参照である必要がありDatagramClientます。

client.jta.append(receivedMessage);
于 2013-09-15T19:09:35.297 に答える