Java Soket Threaded Server 将消息发送回特定客户端



我正在开发一个客户端-服务器Java GUI(Swing(应用程序,我已经成功地创建了一个从客户端接收消息的线程服务器类,以及一个向服务器发送消息的客户端类,客户端和服务器都是GUI应用程序,我正在为我的互联网咖啡馆开发一个局域网排序系统。 我是套接字编程的新手,我现在需要的是一种在服务器 GUI 应用程序的用户通过单击消息到达时更改图标的 JLabel 查看 GUI 中的顺序时从服务器发送到客户端的消息的方法。

那么如何将消息从服务器发送到发送触发该特定 JLabel 的消息的特定客户端?以及如何向包含该消息的客户端用户显示 JOptionpane(客户端有几个 JPanel 类(

发送消息的客户端类:

package questorderingsystem.engine;
import java.io.BufferedWriter; 
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class SendItemAndIp {
private static Socket socket;
public static String message = "";
public static void sendToServer(String item) throws UnknownHostException, IOException{
InetAddress IP= InetAddress.getLocalHost();
String ipadr = IP.toString();
String PCNUM = ipadr.substring(ipadr.length() - 2);
//IP SERVERAA 
String host = "192.168.55.151";
int port = 1978;
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
String oneLine = item.replace("n", "%");
String sendMessage = oneLine +"/"+ PCNUM;
bw.write(sendMessage);
bw.flush();
socket.close();
}
}

线程服务器

package questorderingsystemserver;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class ThreadedEchoServer {
static final int PORT = 1978;
public static void startServer() {
ServerSocket serverSocket = null;
Socket socket = null;
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
socket = serverSocket.accept();
} catch (IOException e) {
System.out.println("I/O error: " + e);
}
// new thread for a client
new EchoThread(socket).start();
}
}
}

回声服务器

package questorderingsystemserver;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JLabel;
public class EchoThread extends Thread {
protected Socket socket;

}
public EchoThread(Socket clientSocket) {
this.socket = clientSocket;
}
public void run() {
InputStream inp = null;
BufferedReader brinp = null;
DataOutputStream out = null;
try {
inp = socket.getInputStream();
brinp = new BufferedReader(new InputStreamReader(inp));
out = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
return;
}
String line;
while (true) {
try {
line = brinp.readLine();
if ((line == null) || line.equalsIgnoreCase("QUIT")) {
socket.close();
return;
} else {
//do something
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
return;
} catch (UnsupportedAudioFileException ex) {
Logger.getLogger(EchoThread.class.getName()).log(Level.SEVERE, null, ex);
} catch (LineUnavailableException ex) {
Logger.getLogger(EchoThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}

套接字建立端到端连接,因此每个套接字都连接到另一个特定的套接字。ServerSocket略有不同。看看ServerSocket::accept的回归.返回的对象是一个Socket。不仅有一个套接字,而且直接连接到发出请求的客户端的套接字。由于您为每个ServerSocket#accept调用创建了一个新EchoThread,因此每个EchoThread都连接到自己的客户端。

您已经在从套接字读取以检查连接是否已关闭或"QUIT 命令"是否已发出。现在,您只需在else-子句中使用之前创建的DataOutputStream进行响应:

while (true) {
try {
line = brinp.readLine();
if ((line == null) || line.equalsIgnoreCase("QUIT")) {
socket.close();
return;
} else {
//writing here:
out.write("Some response textn".getBytes());
out.flush();
}
} catch (IOException e) {
...
} ...
}

但请注意,您的 repsonse 字符串需要以'n'字符结尾,具体取决于您对客户端的"读取逻辑"。

您几乎完成了,因为您将第一个命令指定为"QUIT",因此您可以根据需要实现更多命令。

好的部分是使用BufferedReaderDataOutputStream处理输入和输出。

请注意,如果您喜欢使用字符串进行客户端和服务器之间的通信,因此您可以选择PrintStreamPrintWriter而不是DataOutputStream

在线程服务器文件/类中,在接受套接字后将此行放在 try(现在是安全的(new EchoThread(socket).start();

在客户端类/文件中,当您为服务器发送一些命令时,您可能也期望一些结果。因此,就像您创建的 echo 类一样,您可以对客户端执行相同的操作并处理响应。

最新更新