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

时间:2016-04-21 23:10:38

标签: java multithreading sockets

可以在客户端和服务器之间进行成功的对话。但是,只有在客户端和服务器之间发送一条消息时才会这样做。

示例(作品):

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

示例(不起作用):

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

星号之间的消息不会出现在客户端,直到客户端发送2条消息。根据我的理解,它似乎像一个网络消息系统,其中服务器发送的消息数量必须等于客户端发送的消息数量的n + -1,以显示所有消息。

客户端代码:

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);
                }

            }

        }

服务器端代码:

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);
                }
            }

        }

查看代码我可以看到为什么会发生这种情况,因为While循环初始化后的SOP会停止代码等待1行输入,然后等待发送自己的句子,然后再接收另一个。我尝试将这些内容放在if语句中,但这导致根本没有通信。

我似乎无法弄清楚如何解决这个问题。

如果这需要线程,还有另一种方法吗? (我对线程不太熟悉)

2 个答案:

答案 0 :(得分:1)

根据程序的性质,我建议您使用更多线程来处理消息。

让我们从服务器开始: 如果服务器可以有多个客户端,那么将每个客户端与线程区分开来可能是明智的,例如:

            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();
            }

或者,如果您不希望“会话管理器”成为自定义的可运行类,则可以使用以下内容替换行new Thread(new CustomRunnableClass(s)).start();

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

在客户端,我建议任何从套接字中侦听新消息的类都将被新线程区分:

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();
}

这样客户端监听客户端收到的任何消息,并在接收时运行一个处理它们的方法,并且不会挂起。

希望这有用。

答案 1 :(得分:-1)

你需要非阻塞套接字,如果输入缓冲区中没有数据,读取器函数应该在中间返回。

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