BufferedReader等待请求/响应套接字连接

时间:2018-02-15 13:49:59

标签: java sockets

我正在尝试构建一个简单的请求/响应服务器。

客户端向服务器发送消息。然后,服务器向客户端响应消息。

服务器端代码

package com.techoffice.example;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

import javax.net.ServerSocketFactory;

public class TcpServerAppl {

    static int port = 1010;
    static ServerSocket serverSocket;
    static {
        try {
            serverSocket = ServerSocketFactory.getDefault().createServerSocket(port);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {

        System.out.println("Server is running on " + port);
        while(true){
            Socket socket = null;
            try{        
                socket = serverSocket.accept();
                System.out.println("Someone is connecting to the server");
                InputStream is = socket.getInputStream();
                OutputStream os = socket.getOutputStream();

                PrintWriter printWriter = new PrintWriter(os);

                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));

                // read message from client 
                String line = bufferedReader.readLine();
                while(line != null && line.length() > 0){
                    System.out.println(line);
                    line = bufferedReader.readLine();
                }
//              reader.close();

                // send message to client
                System.out.println("Server starts sending message to client");
                printWriter.println("This is a message sent from server");
                printWriter.flush();
//              printWriter.close();

            } catch(Exception e){
                System.err.println(e.getMessage());
            } finally {
                if (socket != null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        System.err.println(e.getMessage());
                    }
                }
            }
        }

    }
}

客户端代码

package com.techoffice.example;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.net.SocketFactory;

public class TcpClientAppl {
    public static void main(String[] args) throws UnknownHostException, IOException{
        // start socket connection
        Socket socket = SocketFactory.getDefault().createSocket("localhost", 1010);
        PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        // send message to server
        printWriter.println("Send Message From Client" );
        printWriter.flush();
//      printWriter.close();

        // read message from server
        System.out.println("Client starts reading from Server");
        String line = bufferedReader.readLine();
        while(line != null && line.length() > 0){
            System.out.println(line);
            line = bufferedReader.readLine();
        }
//      bufferedReader.close();

        // close scoket connection
        socket.close();
    }
}

服务器在缓冲读卡器处被阻止。但是,如果我尝试通过关闭客户端中的Print Writer来关闭缓冲读取器,则客户端会抛出“连接已关闭”的异常。

众所周知,在PrintWriter或BufferedReader中关闭会关闭套接字连接。

更新

指定请求/消息的结束将是解决方案之一。但在这种情况下,我不希望有一个请求结束。我只想对请求做出响应,无论请求中是否有多行。

2 个答案:

答案 0 :(得分:1)

  

客户端抛出'connection closed'的例外

不,不。如果取消注释merged.tables$Date <-paste(months(as.Date(merged.tables$Date)),year(as.Date(merged.tables$Date)),sep="_") 行,它将抛出异常' socket 关闭'。

但是对你真正的问题。服务器在发送任何内容之前读取行直到流结束:在对等体关闭连接之前,流的结束将永远不会发生;并且对等关闭连接,除了上述情况;所以它永远不会发送任何东西而只是在printWriter.close()中被阻止;所以客户端也会永久阻止readLine()

由于这显然是一个echo服务器,它应该在收到它时回显每一行。

答案 1 :(得分:0)

问题是客户端抛出的异常丢失。也许在通信完成后尝试关闭服务器端的所有内容(读者,编写者)。 BTW。在致电关闭之前,您不需要拨打同花。您也可以在服务器端使用带有套接字的try-catch-withResources