[英]Java Soket Threaded Server sending messages back to specific client
i am developing a Client-Server Java GUI(Swing) application , i have succsesfully created Threaded Server class that receives messages from clients , and a Client class that sends message to the server , both Client and Server are GUI applications , i am developing a lan ordering system for my internet caffe.. I am new to socket programing , what i need now is a way to send a message from Server to Client when user of Server GUI application views the order in a GUI by clicking a JLabel that changes icon when message arrives.. 我正在开发Client-Server Java GUI(Swing)应用程序,成功创建了Threaded Server类,该类从客户端接收消息,并且Client类将消息发送到服务器,Client和Server均为GUI应用程序,我正在开发局域网编程系统。我是套接字编程的新手,现在我需要的是一种方法,当服务器GUI应用程序的用户通过单击更改图标的JLabel在GUI中查看订单时,可以从服务器向客户端发送消息消息到达时..
So how to send a message from the Server to that specific Client that send the message that triggered that specific JLabel ? 那么,如何从服务器向该特定客户端发送消息,该特定客户端发送触发该特定JLabel的消息? And how to show JOptionpane to to Client user containing that message (client has several JPanel classes)
以及如何向包含该消息的客户端用户显示JOptionpane(客户端具有几个JPanel类)
Client class that sends the message: 发送消息的客户端类:
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();
}
}
Threaded Server 线程服务器
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();
}
}
}
EchoServer 回声服务器
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);
}
}
}
}
Sockets establish end-to-end-connections and therefore each socket it connected to another specific one. 套接字建立端到端连接,因此每个套接字都连接到另一个特定的套接字。 A
ServerSocket
is slightly different. ServerSocket
稍有不同。 Take a look at the return of ServerSocket::accept
. 看看
ServerSocket::accept
的返回。 The returned object is a Socket
. 返回的对象是
Socket
。 Not only one socket but the one directly connected to the client who issued a request. 不仅有一个套接字,而且还有一个直接连接到发出请求的客户端的套接字。 Since you create a new
EchoThread
for each ServerSocket#accept
call each EchoThread
has it's of connection to it's own Client. 由于您为每个
ServerSocket#accept
调用创建了一个新的EchoThread
,因此每个EchoThread
都具有与其自己的客户端的连接。
You're already reading from the socket to check if the connection has been closed or 'QUIT command' has been issued. 您已经在从套接字中读取数据,以检查连接是否已关闭或是否发出了“ QUIT命令”。 Now you can simply respond in your
else
-clause with the DataOutputStream
created earlier: 现在你可以在你的回应简单
else
与-clause DataOutputStream
前面创建:
while (true) {
try {
line = brinp.readLine();
if ((line == null) || line.equalsIgnoreCase("QUIT")) {
socket.close();
return;
} else {
//writing here:
out.write("Some response text\n".getBytes());
out.flush();
}
} catch (IOException e) {
...
} ...
}
But note that your repsonse String needs to end with a '\\n'
character, depending on your 'reading logic' of your client. 但是请注意,您的响应字符串必须以
'\\n'
字符结尾,具体取决于客户端的“读取逻辑”。
You are almost done, as you specified the first command as "QUIT", so you may implement more commands as you wish. 正如您将第一个命令指定为“ QUIT”一样,您已经快完成了,因此您可以根据需要实现更多命令。
The good part is handling the input and output using the BufferedReader
and DataOutputStream
. 好的部分是使用
BufferedReader
和DataOutputStream
处理输入和输出。
Please note if you like to work with strings for communication between client and server, so you may go for PrintStream
or PrintWriter
instead of DataOutputStream
. 请注意,如果您想使用字符串进行客户端和服务器之间的通信,则可以使用
PrintStream
或PrintWriter
而不是DataOutputStream
。
in thread server file/class, place this line new EchoThread(socket).start();
在线程服务器文件/类中,将此行放置为
new EchoThread(socket).start();
after you accept the socket in side the try(it's now safe). 在您接受侧面的套接字后,尝试一下(现在是安全的)。
In client class/file, as you send some command for server, then you may expecting some result too. 在客户端类/文件中,当您向服务器发送一些命令时,您可能还会期望得到一些结果。 So just like echo class you created, you may do the same thing for client and process the responses.
因此,就像您创建的echo类一样,您可以对客户端执行相同的操作并处理响应。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.