代码之家  ›  专栏  ›  技术社区  ›  LoneCuriousWolf

如何从TCP服务器向TCP客户端发送应答?

  •  0
  • LoneCuriousWolf  · 技术社区  · 7 年前

    我有以下服务器和客户端代码。客户机能够成功地将数据发送到服务器,但是当客户机尝试从服务器读取数据时,代码将继续运行而不输出任何数据。

    服务器:

    public static void main(String[] args) throws Exception {
    
        ServerSocket s = new ServerSocket(9898);
    
        while(true) {
    
            Socket recv = s.accept();
    
            InputStream inp = recv.getInputStream();
            OutputStream out = recv.getOutputStream();
    
            String data = null;
            BufferedReader in = new BufferedReader(new InputStreamReader(inp));
            while ( (data = in.readLine()) != null ) {
                System.out.println("\r" + data);
            }
    
            out.write("sampleSendToClient".getBytes());
        }
    
    }
    

    客户:

    public static void main(String[] args) throws Exception{
        Socket clientSocket = new Socket("localhost", 9898);
        OutputStream out = clientSocket.getOutputStream();
        InputStream inp = clientSocket.getInputStream();
    
        out.write("sampleSendToServer".getBytes());
    
        String data = null;
        //if I dont write next 4 lines then client exits gracefully 
        //but now it is stuck infinitely
        BufferedReader in = new BufferedReader(new InputStreamReader(inp));
        while ( (data = in.readLine()) != null ) {
            System.out.println("\r" + data);
        }
    
        clientSocket.close();
    }
    

    我无法理解以上代码中的错误。

    1 回复  |  直到 7 年前
        1
  •  0
  •   L.Spillner    7 年前

    通过调用 OutputStream#write(byte[] data) 但是你的客户用 BufferedReader BufferedReader#readLine() 是一个 舞台调度 I/O操作,该操作将挂起其线程,直到 \n \r 角色到达 InputStream (或者流是关闭的,在这种情况下,方法会被 null 返回)。

    服务器发送的字符串不以 \n R 因此,数据可能已经发送,并在客户端的缓冲区中徘徊 缓冲区读取 但是没有那些终止字符 readLine() 永远不会回来。

    简单的改变

    out.write("sampleSendToClient".getBytes());
    

    out.write("sampleSendToClient\n".getBytes());
    

    应该会成功的。

    更新:

    while ( (data = in.readLine()) != null ) {
            System.out.println(data);
        }
    

    这个 while 只有在 RealLoad() 收益率 无效的 只有当流被clsoed时才会出现这种情况。但是,由于无法在不断开连接的情况下关闭流,因此必须找到另一种终止循环的方法,因为现在循环将永远运行。

    即使在添加 \n 你的服务器不会响应,因为他将在那一点无限循环。


    另一方面:对于每个新的连接,您都要覆盖前一个套接字而不关闭它的资源(主要集中在数据流和套接字本身),因此会创建ressource泄漏。考虑在不再需要时关闭每个对象。