创建回显服务器-服务器只能响应一次



我正在创建一个多线程聊天服务器,该服务器应该为每个连接的客户端创建一个单独的线程。每次客户端连接时,我的服务器都会创建一个客户端处理程序类的新实例,该类应该跟踪从/到特定客户端的传入和传出消息。

客户端第一次连接到我的echo服务器时,服务器将以客户端响应的echo进行响应。但是,如果我第二次尝试向服务器发送消息,客户端会创建IOException。我自己创建了客户端应用程序,但我知道它能工作,因为我可以很好地与其他服务器通信。我很确定问题出在这个客户端处理程序类的run方法中,但我不明白为什么它不起作用。下面是我的客户端处理程序类中的run方法:

public void run() {
    try (
        BufferedReader in =
                new BufferedReader(
                    new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = 
            new PrintWriter(clientSocket.getOutputStream());
    ) {
        long time = System.currentTimeMillis();         
        out.println("Server - " + time + ": " + in.readLine());
        out.close();
        try {
            in.close();
        } catch (IOException e) {
            System.err.println("Couldn't close input stream");
        }
    } catch(IOException e) {
        System.err.println("Got an IOException error while reading or writing from/to client");
    }
}

我猜我应该在某个地方有某种while循环,但我所有实现它的尝试都失败了。例如,我试图更改此代码:

long time = System.currentTimeMillis();         
out.println("Server - " + time + ": " + in.readLine());

对此:

String inputLine;
while((inputLine = in.readLine()) != null) {
    long time = System.currentTimeMillis();         
    out.println("Server - " + time + ": " + inputLine);
}

这个解决方案或多或少是oracle网站(http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html)说应该完成。

我认为主要的问题可能是我没有真正掌握服务器/客户端通信的整个概念,所以如果能朝着正确的方向努力,我将不胜感激。

提前感谢!

您提到的Oracle文章中的重要部分是标题为支持多个客户端的部分。

基本的Java套接字API是一个阻塞的API,这基本上意味着您调用一个方法,该方法阻塞直到IO事件发生。如果您需要等待多个IO事件(在您的情况下是传入客户端连接和传入数据),则必须创建多个线程。

文章中显示的服务器只接受一个单独的(客户端)连接,并且在客户端关闭后将关闭,因为服务器上的InputStream将返回null,导致循环终止。

首先,你的服务器需要看起来像这样(这是一个简化的例子):

try (ServerSocket serverSocket = new ServerSocket(portNumber))
{
  while (running)
  {
    Socket clientSocket = serverSocket.accept();
    new Thread(new ClientHandler(clientSocket)).start();
  }
}   

注意:为每个客户端连接启动一个线程说明了这一点,但这大大简化了管理服务器上的连接负载。

客户端代码可以保持原样。

正如我所指出的,这是将线程管理交给开发人员的基础——这通常会导致麻烦,因为人们只是弄错了。正因为如此,Java的套接字API被扩展为创建NIO API-Jakob Jenkov编写了一些很好的教程。

Netty也值得一看,我个人认为它比NIO更容易使用。

最新更新