Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)
来源:互联网 发布:大数据质量管理方案 编辑:程序博客网 时间:2024/05/14 15:00
声明:该博文以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()不会。
测试二:不可以,会抛出异常!
测试三:丢弃
客户端程序:
- package com.test2;
- import java.io.*;
- import java.net.*;
- /**
- * @ClassName: SocketTest
- * @Description: 测试Socket中,流关闭后,socket是否关闭?是否可重开流?输出缓存区的数据是发送出去,还是丢弃?
- * @author 慢跑学Android
- * @date 2011-11-12 上午11:15:21
- *
- */
- public class SocketTest {
- Socket mySocket;
- DataOutputStream dout;
- public static void main(String[] args){
- new SocketTest();
- }
- public SocketTest(){
- // 输出流关闭的测试一:socket关闭吗?
- test1();
- // 输出流关闭测试二:该流是否可以重新开启?
- test2();
- // 输出流关闭测试三:输出缓冲区里的数据是丢弃,还是发送?
- test3();
- }
- private void test1() {
- // 输出流关闭的测试一:socket关闭吗?
- System.out.println("\n****2种方式关闭输出流,Socket是否关闭?***\n");
- try {
- mySocket = new Socket("27.154.122.233",9999);
- } catch (UnknownHostException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- dout = new DataOutputStream(new BufferedOutputStream(mySocket.getOutputStream()));
- //下面这一句主要是用来证明socket确实处于开启状态
- System.out.println("输出流刚打开,Socket是否关闭?" + mySocket.isClosed());
- mySocket.shutdownOutput();
- System.out.println("使用shutdownOutput关闭输出流,Socket是否关闭?" + mySocket.isClosed());
- dout.close();
- System.out.println("使用close关闭输出流,Socket是否关闭?" + mySocket.isClosed());
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- private void test2() {
- // 输出流关闭测试二:使用shutdownOutputStream后,输出流是否可以重新开启?
- System.out.println("\n****使用shutdownOutputStream后,输出流是否可以重新开启?***\n");
- try {
- mySocket = new Socket("27.154.122.233",9999);
- } catch (UnknownHostException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- dout = new DataOutputStream(new BufferedOutputStream(mySocket.getOutputStream()));
- mySocket.shutdownOutput();
- // 重开输出流
- dout = new DataOutputStream(mySocket.getOutputStream());
- dout.writeUTF("是否允许我重开?");
- // 清空输出缓存,确保当dout通道没问题时,消息可以到达服务器
- dout.flush();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- mySocket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- private void test3(){
- // 输出流关闭测试三:输出缓冲区里的数据是丢弃,还是发送?
- System.out.println("\n***输出缓冲区里的数据是丢弃,还是发送?****\n");
- try {
- mySocket = new Socket("27.154.122.233",9999);
- } catch (UnknownHostException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- dout = new DataOutputStream(new BufferedOutputStream(mySocket.getOutputStream()));
- dout.writeUTF("shutdownOutput后,数据发得得出去吗?");
- mySocket.shutdownOutput();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
服务器端程序:
- /**
- * @Title: ServerSocketTest.java
- * @Package com.test1
- * @Description: TODO(该文件为”Socket中,流关闭后,发生什么事“的Sever测试端)
- * @author 慢跑学Android
- * @date 2011-11-12 上午11:31:05
- * @version V1.0
- */
- package com.test1;
- import java.io.*;
- import java.net.*;
- public class ServerSocketTest extends Thread{
- private ServerSocket myServerSocket;
- private final int PORT = 9999;
- public static void main(String[] args){
- ServerSocketTest sst = new ServerSocketTest();
- sst.start();
- }
- public ServerSocketTest(){
- // 初始化一个ServeSocket端
- try {
- myServerSocket = new ServerSocket(PORT);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public void run(){
- while(true){
- System.out.println("我是服务器,我在9999端口监听....");
- try {
- Socket socket = myServerSocket.accept();
- DataInputStream din = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
- String msgIn = din.readUTF();
- System.out.println(msgIn.trim());
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
说明一点:
在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)
- Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)
- Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)
- Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)
- Java socket中IO流的关闭问题
- 输出流关闭造成的Socket关闭
- Java IO包装流如何关闭?(关闭顺序)
- java io 流的关闭
- 【JAVA】IO流关闭顺序
- Java中为IO流写一个快速关闭流的小工具
- Java中为IO流写一个快速关闭流的小工具
- IO流操作后 关闭顺序
- 关闭输出流时Socket的行为(stackoverflow)
- java中io各种流的关闭顺序
- java中io各种流的关闭顺序
- java中io各种流的关闭顺序
- Java的IO操作中关闭流的注意点
- java中io各种流的关闭顺序
- Java中怎么判断一个io流是否已经关闭?
- ubuntu maven环境安装配置以及工程创建
- TOJ 2950.PATULJCI
- springmvc 原理图文解释
- 将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5
- sun.misc.BASE64Encoder找不到jar包的解决方法
- Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)
- 智能指针
- Java并发:三种线程抽象以及线程执行
- 华为的三道笔试OJ题
- com/android/dx/command/dexer/Main : Unsupported major.minor version 52.0
- 输入子系统
- leetcode 53. Maximum Subarray
- 教你如何在树莓派上搭建语音识别服务
- git分支&标签