在客户端和服务端的数据交互完成后,一般需要关闭网络连接。对于服务端来说,需要关闭
Socket
和
ServerSocket
。
在关闭Socket
后,客户端并不会马上感知自已的Socket
已经关闭,也就是说,在服务端的Socket
关闭后,客户端的Socket
的isClosed
和isConnected
方法仍然会分别得到false
和true
。但对已关闭的Socket
的输入输出流进行操作会抛出一个SocketException
异常。
在关闭服务端的ServerSocket
后,ServerSocket
对象所绑定的端口被释放。这时客户端将无法连接服务端程序。下面的代码
演示了在服务端关闭Socket
后,客户端是所何反应的。
package
server;
import java.net. * ;
class Client
{
public static void main(String[] args) throws Exception
{
Socket socket = new Socket( " 127.0.0.1 " , 1234 );
Thread.sleep( 1000 );
// socket.getOutputStream().write(1);
System.out.println( " read() = " + socket.getInputStream().read());
System.out.println( " isConnected() = " + socket.isConnected());
System.out.println( " isClosed() = " + socket.isClosed());
}
}
public class CloseSocket
{
public static void main(String[] args) throws Exception
{
ServerSocket serverSocket = new ServerSocket( 1234 );
while ( true )
{
Socket socket = serverSocket.accept();
socket.close();
}
}
}
import java.net. * ;
class Client
{
public static void main(String[] args) throws Exception
{
Socket socket = new Socket( " 127.0.0.1 " , 1234 );
Thread.sleep( 1000 );
// socket.getOutputStream().write(1);
System.out.println( " read() = " + socket.getInputStream().read());
System.out.println( " isConnected() = " + socket.isConnected());
System.out.println( " isClosed() = " + socket.isClosed());
}
}
public class CloseSocket
{
public static void main(String[] args) throws Exception
{
ServerSocket serverSocket = new ServerSocket( 1234 );
while ( true )
{
Socket socket = serverSocket.accept();
socket.close();
}
}
}
测试
执行下面的命令
执行下面的命令
java server.CloseSocket
java server.Client
java server.Client
运行结果
read()
=
-
1
isConnected() = true
isClosed() = false
isConnected() = true
isClosed() = false
从上面的运行结果可以看出例程
Client
并未抛出
SocketException
异常。而在
012
行的
read
方法返回了
-1
。如果将
socket.close去掉
,客户端的read方法
将处于阻塞状态。这是因为
Java
在发现无法从服务端的
Socket
得到数据后,就通过
read
方法返回了
-1
。如果将
011
行的注释去掉,
Client
就会抛出一个
SocketException
异常。大家可以试试,并
socket.close
行改成
serverSocket.close
后,客户端就会抛出连接异常:
Exception in thread
"
main
"
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java: 168 )
at java.net.SocketInputStream.read(SocketInputStream.java: 182 )
at chapter5.Client.main(CloseSocket.java: 12 )
at java.net.SocketInputStream.read(SocketInputStream.java: 168 )
at java.net.SocketInputStream.read(SocketInputStream.java: 182 )
at chapter5.Client.main(CloseSocket.java: 12 )
显式地调用close
方法关闭ServerSocket
并不是必须的,在程序退出时将自动关闭ServerSocket
。但通过close
方法关闭ServerSocket
,可以使其他的ServerSocket
对象绑定该端口。可以使用ServerSocket
类的isClosed
和isBound
方法判断ServerSocket
是否处于活动状态,如下面的代码所示:
ServerSocket serverSocket
=
new
ServerSocket(
1234
);
if (serverSocket.isBound() == true && serverSocket.isClosed() == false )
System.out.println( " serverSocket处于活动状态! " );
else
System.out.println( " serverSocket处于非活动状态! " );
if (serverSocket.isBound() == true && serverSocket.isClosed() == false )
System.out.println( " serverSocket处于活动状态! " );
else
System.out.println( " serverSocket处于非活动状态! " );
上面代码所示的“非活动状态”可能是serverSocket
对象已经关闭,也可能是serverSocket
对象是使用ServerSocket
类的默认构造方法创建的,而且未调用bind
方法绑定端口。在这里要注意的是isBound
方法返回true
并不意味着serverSocket
对象处于活动状态,调用close
方法并不会将绑定状态置为false
。这一点和Socket
类的isConnected
方法类似。
本文转自 androidguy 51CTO博客,原文链接:
http://blog.51cto.com/androidguy/214352
,如需转载请自行联系原作者