首页 新闻 会员 周边 捐助

问一个socket的基本问题

0
悬赏园豆:20 [已解决问题] 解决于 2019-05-29 19:11

服务器代码:

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

小光的主页 小光 | 小虾三级 | 园豆:1766
提问于:2019-05-29 16:00
< >
分享
最佳答案
0

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

收获园豆:20
海之殇 | 菜鸟二级 |园豆:500 | 2019-05-29 18:04
其他回答(2)
0

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

花飘水流兮 | 园豆:13617 (专家六级) | 2019-05-29 16:50

是这样的,我把服务器端的while去掉,就执行一次,把socket.close()也注释掉,还是有问题,

ServerSocket serverSocket = new ServerSocket(6666);
Socket socket = serverSocket.accept();

    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();

// socket.close();

服务器打印客户端发送的消息

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();

    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();

// socket.close();

报错:
Exception in thread "main" java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:903)

客户端在发完消息后获取getInputStream()会报错,这是为什么,我都没关socket,我在网上查的socket自动断开很长时间的,难道是我客户端和服务器用一台机子的问题?

支持(0) 反对(0) 小光 | 园豆:1766 (小虾三级) | 2019-05-29 17:09
0

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

小光 | 园豆:1766 (小虾三级) | 2019-05-29 17:48
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册