简体   繁体   English

Java Socket客户端/服务器对一次只能发送一条消息

[英]Java Socket client/server pair can only send one message at a time

A successful conversation can be carried out between the client and the server. 可以在客户端和服务器之间进行成功的对话。 However this is only if one message is sent between the client and server. 但是,这仅在客户端和服务器之间发送一条消息的情况下。

Example (Works): 示例(工程):

Client: Hello
Server: helloo
Client: what time is it
Server: Let me get that for you

Example (Does not work): 示例(不起作用):

Client: Hello
Server: helloo
Server: *How are you today*
Server: *test message*
Client: Yes

The messages between the asterisks do not appear on the client side untill the client sends 2 messages. 在客户端发送2条消息之前,星号之间的消息不会出现在客户端上。 From what I understand it seems to work like a net-message system where the number of messages sent by the server has to equal n+-1 the number of messages sent by the client, for all the messages to be shown. 据我了解,它似乎像一个网络消息系统一样工作,其中对于所有要显示的消息,服务器发送的消息数必须等于客户端发送的消息数的n + -1。

Client Side Code: 客户端代码:

try {
            Socket client_socket= new Socket(hostname,port_number);
            PrintWriter output = new PrintWriter(client_socket.getOutputStream(),true);
            BufferedReader input = new BufferedReader(new InputStreamReader(client_socket.getInputStream()));
            BufferedReader stdIn=new BufferedReader(new InputStreamReader(System.in));

            String fromUser,fromServer;
            while ((fromServer=input.readLine())!=null) {
                System.out.println("Server: "+fromServer);
                if (fromServer.equals("Quit")) {
                    break;
                } 
                fromUser=stdIn.readLine();
                if (fromUser!=null) {
                    System.out.println("Client: "+fromUser);
                    output.println(fromUser);
                }

            }

        }

Server Side Code: 服务器端代码:

try {
            ServerSocket server_socket=new ServerSocket(port_number);
            Socket client_socket= server_socket.accept();
            PrintWriter output = new PrintWriter(client_socket.getOutputStream(),true);
            BufferedReader input = new BufferedReader(new InputStreamReader(client_socket.getInputStream()));
            BufferedReader stdIn=new BufferedReader(new InputStreamReader(System.in));
            output.println("Established");
            String fromUser, fromServer;
            while ((fromUser=input.readLine())!=null) {
                System.out.println("Client: "+fromUser);
                if (fromUser.equals("Quit")) {
                    break;
                } 
                fromServer=stdIn.readLine();
                if (fromServer!=null) {
                    System.out.println("Server: "+fromServer);
                    output.println(fromServer);
                }
            }

        }

Looking at the code I can see why this would happen, its because the SOP after the While loop initialization stops the code waiting for 1 line of input, and then waits to send its own sentence, before receiving another. 查看代码,我会明白为什么会发生这种情况,这是因为While循环初始化之后的SOP停止了代码等待1行输入,然后等待发送自己的语句,然后再接收另一个语句。 I tried putting these within the if statements, but this results in no communication at all. 我尝试将它们放在if语句中,但这根本导致无法进行通信。

I cant seem to figure out how to fix this. 我似乎无法弄清楚如何解决此问题。

If this requires threads, is there another way? 如果这需要线程,还有其他方法吗? (i'm not too familiar with threads) (我对线程不太熟悉)

Depending on the nature of your program, i would advise you to use more threads to handle messaging. 根据您程序的性质,我建议您使用更多线程来处理消息传递。

Lets start with the server: If the server can have multiple clients, than it probably would be wise to distinguish every client with a thread, for example: 让我们从服务器开始:如果服务器可以有多个客户端,那么用线程来区分每个客户端可能是明智的,例如:

            ServerSocket ss;

            try {
                ss = new ServerSocket(portIn);
                while (true) {
                    Socket s = ss.accept();
                    // Option 1: runnable class
                    new Thread(new CustomRunnableClass(s)).start();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

Or if you dont want your "session manager" to be a custom runnable class, you can replace the line new Thread(new CustomRunnableClass(s)).start(); 或者,如果您不希望“会话管理器”成为自定义可运行类,则可以替换new Thread(new CustomRunnableClass(s)).start(); with the following 与以下

new Thread(new Runnable() {
   @Override
   public void run() {
        new SomeClass().runThisClass();
   }
}

On the client side i would suggest that whatever class that listens to new messages from sockets will be distinguished by a new thread: 在客户端,我建议通过新线程来区分侦听套接字中新消息的任何类:

private void startListening() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            for(;;) {
                String msg = dis.readUTF();
                System.out.println("  ----- Recieved New Message -----\n" + msg);
                for (IMessageListener listener : listeners) {
                    try {
                        listener.onMessageRecieved(msg);
                    } catch (Exception e) {

                    }
                }
            }
        }
    }).start();
}

this way the client listens to any message received by the client and runs a method to handle them upon receiving, and is not hung in the meanwhile. 这样,客户端可以侦听客户端接收到的任何消息,并运行一种方法以在接收到消息时对其进行处理,并且同时不会被挂起。

Hope this was helpful. 希望这会有所帮助。

you need non-blocking sockets, the reader function should return intermediately if there is no data in the input buffer. 如果您需要非阻塞套接字,则在输入缓冲区中没有数据的情况下,读取器函数应在中间返回。

http://www.java2s.com/Tutorials/Java/Java_Network/0070__Java_Network_Non-Blocking_Socket.htm http://www.java2s.com/Tutorials/Java/Java_Network/0070__Java_Network_Non-Blocking_Socket.htm

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM