Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 确保客户机请求得到正确响应_Java_Sockets - Fatal编程技术网

Java 确保客户机请求得到正确响应

Java 确保客户机请求得到正确响应,java,sockets,Java,Sockets,寻找以下问题的建议 我正在开发一个应用程序(客户端),它使用一个TCP套接字向服务器读写消息 消息是到达时将被解析的几种预定义类型之一 服务器可以随时广播消息 客户端将向服务器发送消息,并期望得到响应。然而(这就是我的问题所在),我无法从套接字中读取以接收此消息,因为我不知道何时可以发送此消息。大多数情况下,客户机响应消息将在客户机请求之后立即传递。但是,偶尔会先发送另一条广播消息 套接字的读取通道由单个生产者线程排入阻塞队列。在一个单独的使用者线程中,任何消息都将被排在队列中并发送以供进一步处

寻找以下问题的建议

我正在开发一个应用程序(客户端),它使用一个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);
        }
    }
}
我不确定这段代码是否可以编译,但您的服务器实现可能看起来非常类似,并且具有可扩展性和健壮性


您的客户机可以几乎相同,尽管您将使用套接字而不是服务器套接字,并且可能会以不同的方式处理消息。

这里没有看到序列化的作用。另外,请看我的编辑。无论如何,谢谢你。