问一个socket的基本问题

2019-05-29 18:53发布

服务器代码:

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只能进行一次读或者写的操作,第二次操作流就会失败?

标签: Socket
3条回答
smile是对你的礼貌
2楼-- · 2019-05-29 19:10

以找到原因,多谢@海之殇
在关闭从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;
}

查看更多
三岁会撩人
3楼-- · 2019-05-29 19:16

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

查看更多
beautiful°
4楼-- · 2019-05-29 19:29

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后开线程。

查看更多
登录 后发表回答