Java 确保客户机请求得到正确响应
寻找以下问题的建议 我正在开发一个应用程序(客户端),它使用一个TCP套接字向服务器读写消息 消息是到达时将被解析的几种预定义类型之一 服务器可以随时广播消息 客户端将向服务器发送消息,并期望得到响应。然而(这就是我的问题所在),我无法从套接字中读取以接收此消息,因为我不知道何时可以发送此消息。大多数情况下,客户机响应消息将在客户机请求之后立即传递。但是,偶尔会先发送另一条广播消息 套接字的读取通道由单个生产者线程排入阻塞队列。在一个单独的使用者线程中,任何消息都将被排在队列中并发送以供进一步处理。为了获得预期的客户机响应,我是否应该使用事件源/侦听器习惯用法,在客户机(以及如果)响应到达时通知他们 谢谢你的建议Java 确保客户机请求得到正确响应,java,sockets,Java,Sockets,寻找以下问题的建议 我正在开发一个应用程序(客户端),它使用一个TCP套接字向服务器读写消息 消息是到达时将被解析的几种预定义类型之一 服务器可以随时广播消息 客户端将向服务器发送消息,并期望得到响应。然而(这就是我的问题所在),我无法从套接字中读取以接收此消息,因为我不知道何时可以发送此消息。大多数情况下,客户机响应消息将在客户机请求之后立即传递。但是,偶尔会先发送另一条广播消息 套接字的读取通道由单个生产者线程排入阻塞队列。在一个单独的使用者线程中,任何消息都将被排在队列中并发送以供进一步处
编辑:我想我的问题还不清楚,因为到目前为止的建议没有涉及到手头的问题。最后,我确实使用了事件源/侦听器习惯用法来处理这个问题。再次感谢您的错误,但我认为这是关闭的。主持人甚至可能想删除这个问题。这是使用Java序列化机制的绝佳机会。您可以这样做(假设您捕获了所有相关的异常,为了简洁起见省略了这些异常) 您的邮件中甚至可以有回调,以便 类登录消息{
public final String username;
public final String password;
public LoginMessage(String username, String password) {
this.username = username;
this.password = password;
}
public void callback(ClientListeningThread thread, ServerProcessor engine) {
ServerMessage response = engine.attemptLogin(username,password);
thread.send(response);
}
}
在你的引擎里
while(!requests.isEmpty()) {
ClientRequest request = requests.poll();
ClientListeningThread = request.thread;
ClientMessage message = request.message;
request.callback(thread,this);
}
您可以使用侦听器和缓存线程池来实现它。因此,您可以创建一个可运行类来处理消息。然后创建一个侦听器类,该类只实例化一个套接字(或服务器套接字)并创建一个线程池。在侦听器类中,创建一个无限while循环,用于侦听传入的请求,并将socket.accept传递到可运行对象的构造函数中,以便它可以处理来自套接字的任何输入 代码将如下所示:
public class MessageHandler implements Runnable {
String msg = "";
Socket socket = null;
BufferedReader in = null;
PrintWriter out = null;
public void MessageHandler(ServerSocket socket){
this.socket = socket;
}
@Override
public void run(){
//Message read from socket
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Message: " + in.readLine());
//Reply send back through same socket
out = new PrintWriter(socket.getOutputStream(), true);
out.println("MESSAGE RECEIVED. THANKS.");
}
}
public class SocketListener {
ServerSocket socket = null;
ExecutorService threadExecutor = null;
Runnable runnable = null;
public static void main (String[] args){
socket = new ServerSocket(8181);
/* Socket will always be listening, when a request arrives a thread will handle
* the incoming stream.
*/
while(true) {
threadExecutor = Executors.newCachedThreadPool();
runnable = new MessageHandler(socket.accept);
threadExecutor.execute(runnable);
}
}
}
你们的听力课看起来是这样的:
public class MessageHandler implements Runnable {
String msg = "";
Socket socket = null;
BufferedReader in = null;
PrintWriter out = null;
public void MessageHandler(ServerSocket socket){
this.socket = socket;
}
@Override
public void run(){
//Message read from socket
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Message: " + in.readLine());
//Reply send back through same socket
out = new PrintWriter(socket.getOutputStream(), true);
out.println("MESSAGE RECEIVED. THANKS.");
}
}
public class SocketListener {
ServerSocket socket = null;
ExecutorService threadExecutor = null;
Runnable runnable = null;
public static void main (String[] args){
socket = new ServerSocket(8181);
/* Socket will always be listening, when a request arrives a thread will handle
* the incoming stream.
*/
while(true) {
threadExecutor = Executors.newCachedThreadPool();
runnable = new MessageHandler(socket.accept);
threadExecutor.execute(runnable);
}
}
}
我不确定这段代码是否可以编译,但您的服务器实现可能看起来非常类似,并且具有可扩展性和健壮性
您的客户机可以几乎相同,尽管您将使用套接字而不是服务器套接字,并且可能会以不同的方式处理消息。这里没有看到序列化的作用。另外,请看我的编辑。无论如何,谢谢你。