博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
阅读量:5010 次
发布时间:2019-06-12

本文共 7205 字,大约阅读时间需要 24 分钟。

声明:该博文以socket中,关闭输出流为例进行说明。

 

为了方便讲解,我们把DataOutputstream dout = new DataOutputStream(new BufferedOutputStream(mySocket.getOutputStream()));中的dout做为Socket输出流的代言。同样的,din是输入流的代言。

可以造成dout被关闭的操作有:

1、调用dout.close();或din.close();因为使用这种流关闭,会造成socket被关闭,所以输入输出流都将不可再用。

2、调用socket.close();

3、调用socket.shutdownOutputStream();单方面关闭dout,此时din还可正常使用。

 

以下,我将对socket中关闭输出流进行3个测试:

输出流关闭测试一:socket关闭吗?
输出流关闭测试二:该流是否可以重新开启?
输出流关闭测试三:输出缓冲区里的数据是丢弃,还是发送?

 测试结果如下:

测试一:dout.close();会造成socket被关闭,但socket.shutdownOutputStream()不会。

测试二:不可以,会抛出异常!

测试三:丢弃

微笑客户端程序:

 

01.package com.test2;  02.import java.io.*;  03.import java.net.*;  04./** 05.* @ClassName: SocketTest 06.* @Description: 测试Socket中,流关闭后,socket是否关闭?是否可重开流?输出缓存区的数据是发送出去,还是丢弃? 07.* @author 慢跑学Android 08.* @date 2011-11-12 上午11:15:21 09.*  10.*/  11.public class SocketTest {  12.    Socket mySocket;  13.    DataOutputStream dout;  14.    public static void main(String[] args){  15.        new SocketTest();  16.    }  17.      18.    public SocketTest(){  19.        // 输出流关闭的测试一:socket关闭吗?   20.        test1();  21.        // 输出流关闭测试二:该流是否可以重新开启?   22.        test2();  23.        // 输出流关闭测试三:输出缓冲区里的数据是丢弃,还是发送?   24.        test3();  25.    }  26.  27.    private void test1() {  28.        // 输出流关闭的测试一:socket关闭吗?   29.        System.out.println("\n****2种方式关闭输出流,Socket是否关闭?***\n");  30.        try {  31.            mySocket = new Socket("27.154.122.233",9999);  32.        } catch (UnknownHostException e) {  33.            e.printStackTrace();  34.        } catch (IOException e) {  35.            e.printStackTrace();  36.        }  37.          38.        try {  39.            dout = new DataOutputStream(new BufferedOutputStream(mySocket.getOutputStream()));  40.            //下面这一句主要是用来证明socket确实处于开启状态   41.            System.out.println("输出流刚打开,Socket是否关闭?" + mySocket.isClosed());  42.            mySocket.shutdownOutput();  43.            System.out.println("使用shutdownOutput关闭输出流,Socket是否关闭?" + mySocket.isClosed());  44.            dout.close();  45.            System.out.println("使用close关闭输出流,Socket是否关闭?" + mySocket.isClosed());  46.        } catch (IOException e) {  47.            e.printStackTrace();  48.        }  49.    }  50.  51.    private void test2() {  52.        // 输出流关闭测试二:使用shutdownOutputStream后,输出流是否可以重新开启?   53.        System.out.println("\n****使用shutdownOutputStream后,输出流是否可以重新开启?***\n");  54.        try {  55.            mySocket = new Socket("27.154.122.233",9999);  56.        } catch (UnknownHostException e) {  57.            e.printStackTrace();  58.        } catch (IOException e) {  59.            e.printStackTrace();  60.        }  61.          62.        try {  63.            dout = new DataOutputStream(new BufferedOutputStream(mySocket.getOutputStream()));  64.            mySocket.shutdownOutput();  65.            // 重开输出流   66.            dout = new DataOutputStream(mySocket.getOutputStream());  67.            dout.writeUTF("是否允许我重开?");  68.            // 清空输出缓存,确保当dout通道没问题时,消息可以到达服务器   69.            dout.flush();  70.        } catch (IOException e) {  71.            e.printStackTrace();  72.        } finally {  73.            try {  74.                mySocket.close();  75.            } catch (IOException e) {  76.                e.printStackTrace();  77.            }  78.        }  79.    }  80.      81.    private void test3(){  82.        // 输出流关闭测试三:输出缓冲区里的数据是丢弃,还是发送?   83.        System.out.println("\n***输出缓冲区里的数据是丢弃,还是发送?****\n");  84.        try {  85.            mySocket = new Socket("27.154.122.233",9999);  86.        } catch (UnknownHostException e) {  87.            e.printStackTrace();  88.        } catch (IOException e) {  89.            e.printStackTrace();  90.        }  91.          92.        try {  93.            dout = new DataOutputStream(new BufferedOutputStream(mySocket.getOutputStream()));  94.            dout.writeUTF("shutdownOutput后,数据发得得出去吗?");  95.            mySocket.shutdownOutput();  96.        } catch (IOException e) {  97.            e.printStackTrace();  98.        }  99.    }  100.}

 

 

微笑服务器端程序:

 

01./**    02.* @Title: ServerSocketTest.java 03.* @Package com.test1 04.* @Description: TODO(该文件为”Socket中,流关闭后,发生什么事“的Sever测试端) 05.* @author 慢跑学Android 06.* @date 2011-11-12 上午11:31:05 07.* @version V1.0    08.*/  09.package com.test1;  10.  11.import java.io.*;  12.import java.net.*;  13.  14.public class ServerSocketTest extends Thread{  15.    private ServerSocket myServerSocket;  16.    private final int PORT = 9999;  17.    public static void main(String[] args){  18.        ServerSocketTest sst = new ServerSocketTest();  19.        sst.start();  20.    }  21.      22.    public ServerSocketTest(){  23.        // 初始化一个ServeSocket端   24.        try {  25.            myServerSocket = new ServerSocket(PORT);  26.        } catch (IOException e) {  27.            e.printStackTrace();  28.        }  29.    }  30.      31.    public void run(){  32.        while(true){  33.            System.out.println("我是服务器,我在9999端口监听....");  34.            try {  35.                Socket socket = myServerSocket.accept();  36.                DataInputStream din = new DataInputStream(new BufferedInputStream(socket.getInputStream()));  37.                String msgIn = din.readUTF();  38.                System.out.println(msgIn.trim());  39.            } catch (IOException e) {  40.                e.printStackTrace();  41.            }  42.        }  43.    }  44.}

 

 

说明一点:

在test3()中,因为dout = new DataOutputStream(newBufferedOutputStream(mySocket.getOutputStream()));使用了Buffered,所以在dout.writeUTF()方法后,如果没有使用dout.flush();数据会存在输出缓存中,不会发送出去的

如果我们队dout的声明是,dout = new DataOutputStream(mySocket.getOutputStream());那么,数据会立即发送出去。(除非,对方没有调用read()来读取数据,且数据量极大,超过了对方的输入缓存。不过,此时dout.writeUTF();这里会堵塞。)

以下是程序运行后,客户端与服务器各自的控制台输出情况

----------------------------------客户端--------------------------

java.net.SocketException: Socket output is shutdown

 at java.net.Socket.getOutputStream(Unknown Source)
 at com.test2.SocketTest.test2(SocketTest.java:66)
 at com.test2.SocketTest.<init>(SocketTest.java:22)
 at com.test2.SocketTest.main(SocketTest.java:15)

****2种方式关闭输出流,Socket是否关闭?***

输出流刚打开,Socket是否关闭?false

使用shutdownOutput关闭输出流,Socket是否关闭?false
使用close关闭输出流,Socket是否关闭?true

****使用shutdownOutputStream后,输出流是否可以重新开启?***

***输出缓冲区里的数据是丢弃,还是发送?****

 

---------------------------------服务器------------------------------

我是服务器,我在9999端口监听....

我是服务器,我在9999端口监听....
java.io.EOFException
 at java.io.DataInputStream.readUnsignedShort(Unknown Source)
 at java.io.DataInputStream.readUTF(Unknown Source)
 at java.io.DataInputStream.readUTF(Unknown Source)
 at com.test1.ServerSocketTest.run(ServerSocketTest.java:37)
java.io.EOFException
 at java.io.DataInputStream.readUnsignedShort(Unknown Source)
 at java.io.DataInputStream.readUTF(Unknown Source)
 at java.io.DataInputStream.readUTF(Unknown Source)
 at com.test1.ServerSocketTest.run(ServerSocketTest.java:37)
java.io.EOFException
 at java.io.DataInputStream.readUnsignedShort(Unknown Source)

我是服务器,我在9999端口监听....

 at java.io.DataInputStream.readUTF(Unknown Source)

 at java.io.DataInputStream.readUTF(Unknown Source)
 at com.test1.ServerSocketTest.run(ServerSocketTest.java:37)

 

 

 

转载于:https://www.cnblogs.com/alex2520/archive/2013/01/17/2863901.html

你可能感兴趣的文章
iOS获取设备IP地址
查看>>
JavaSE| String常用方法
查看>>
NRF51822配对绑定要点
查看>>
C语言博客作业—数据类型
查看>>
[leetcode]Count and Say
查看>>
cookie、session和token的概念入门
查看>>
保护网站页面内容+版权
查看>>
Golang模拟客户端POST表单功能文件上传
查看>>
重启进程
查看>>
js 进度条效果
查看>>
RelativeLayout
查看>>
Beta冲刺(8/7)——2019.5.30
查看>>
增加列、修改列,增加主键,重设标识列
查看>>
FlexPaper Hightlight 思路
查看>>
UVA 10010 - Where's Waldorf?
查看>>
request的其他功能
查看>>
完结篇OO总结
查看>>
boostrap插件---typeahead.js---输入提示下拉菜单
查看>>
iOS 网络篇 -- 思维导图
查看>>
Extjs4.2 TabPanel中使用Ext.ux.IFrame组件加载内容页面
查看>>