问一个socket的基本问题

2019-05-29 19:09发布

问题:

服务器代码:

public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(6666);
while (true){
Socket socket = serverSocket.accept();
OutputStream os = socket.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
bw.write("我是服务器");
bw.close();
os.close();

        socket.close();
    }

客户端代码:
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1",6666);

    System.out.println("111111111");
    InputStream is = socket.getInputStream();
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    String data = null;
    while ((data = br.readLine()) != null){
        System.out.println(data);
    }
    br.close();
    is.close();
    System.out.println("2222222222");

    socket.close();
}

这样是没问题的,客户端读出来服务器写入的信息,但是如果客户端有两个数据流的操作就会报错:Exception in thread "main" java.net.SocketException: Socket is closed,网上查了原因是在自己关闭了socket后进行了流的读写操作,但是我是在最后关闭socket的,
出问题的客户端代码:

public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1",6666);
OutputStream os = socket.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
bw.write("我是客户端");
bw.close();
os.close();

    System.out.println("111111111");
    InputStream is = socket.getInputStream();
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    String data = null;
    while ((data = br.readLine()) != null){
        System.out.println(data);
    }
    br.close();
    is.close();
    System.out.println("2222222222");

    socket.close();
}

这样会成功执行到打印“1111111”,发送给服务器数据成功,接受服务器信息报错
如果把读写顺序反过来:

public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1",6666);

    InputStream is = socket.getInputStream();
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    String data = null;
    while ((data = br.readLine()) != null){
        System.out.println(data);
    }
    br.close();
    is.close();

    System.out.println("111111111");
    OutputStream os = socket.getOutputStream();
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
    bw.write("我是客户端");
    bw.close();
    os.close();
    System.out.println("2222222222");

    socket.close();
}

这样读数据会成功,写数据就会失败。
为什么客户端对socket只能进行一次读或者写的操作,第二次操作流就会失败?

回答1:

关闭返回的 OutputStream 将关闭关联套接字



回答2:

while (true){
Socket socket = serverSocket.accept();
OutputStream os = socket.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
bw.write("我是服务器");
bw.close();
os.close();

    socket.close();
}

都特么关闭了,就是一次while 流程。重新连你就可以再次该过程了。服务器会对应很多这个过程,你需要在accept后开线程。



回答3:

以找到原因,多谢@海之殇
在关闭从socket获取的输出流或输出流时,(Out/In)putStream.close()方法会指向(Out/In)putStream的子类Socket(Out/In)putStream的close方法,关闭关联的socket,源码如下:

/**
* Closes the stream.
*/
private boolean closing = false;
public void close() throws IOException {
// Prevent recursion. See BugId 4484411
if (closing)
return;
closing = true;
if (socket != null) {
if (!socket.isClosed())
socket.close();
} else
impl.close();
closing = false;
}



标签: Socket