本文為原創(chuàng),如需轉(zhuǎn)載,請(qǐng)注明作者和出處,謝謝!
上一篇:Java網(wǎng)絡(luò)編程從入門到精通(26):在服務(wù)端接收和發(fā)送數(shù)據(jù)
在客戶端和服務(wù)端的數(shù)據(jù)交互完成后,一般需要關(guān)閉網(wǎng)絡(luò)連接。對(duì)于服務(wù)端來說,需要關(guān)閉Socket和ServerSocket。
在關(guān)閉Socket后,客戶端并不會(huì)馬上感知自已的Socket已經(jīng)關(guān)閉,也就是說,在服務(wù)端的Socket關(guān)閉后,客戶端的Socket的isClosed和isConnected方法仍然會(huì)分別得到false和true。但對(duì)已關(guān)閉的Socket的輸入輸出流進(jìn)行操作會(huì)拋出一個(gè)SocketException異常。
在關(guān)閉服務(wù)端的ServerSocket后,ServerSocket對(duì)象所綁定的端口被釋放。這時(shí)客戶端將無法連接服務(wù)端程序。下面的代碼演示了在服務(wù)端關(guān)閉Socket后,客戶端是所何反應(yīng)的。
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();
}
}
}
測(cè)試
執(zhí)行下面的命令
java server.CloseSocket
java server.Client
運(yùn)行結(jié)果
read() = -1
isConnected() = true
isClosed() = false
從上面的運(yùn)行結(jié)果可以看出例程Client并未拋出SocketException異常。而在012行的read方法返回了-1。如果將socket.close去掉,客戶端的read方法將處于阻塞狀態(tài)。這是因?yàn)?/span>Java在發(fā)現(xiàn)無法從服務(wù)端的Socket得到數(shù)據(jù)后,就通過read方法返回了-1。如果將011行的注釋去掉,Client就會(huì)拋出一個(gè)SocketException異常。大家可以試試,并socket.close行改成serverSocket.close后,客戶端就會(huì)拋出連接異常:
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)
顯式地調(diào)用close方法關(guān)閉ServerSocket并不是必須的,在程序退出時(shí)將自動(dòng)關(guān)閉ServerSocket。但通過close方法關(guān)閉ServerSocket,可以使其他的ServerSocket對(duì)象綁定該端口。可以使用ServerSocket類的isClosed和isBound方法判斷ServerSocket是否處于活動(dòng)狀態(tài),如下面的代碼所示:
ServerSocket serverSocket = new ServerSocket(1234);
if (serverSocket.isBound() == true && serverSocket.isClosed() == false)
System.out.println("serverSocket處于活動(dòng)狀態(tài)!");
else
System.out.println("serverSocket處于非活動(dòng)狀態(tài)!");
上面代碼所示的“非活動(dòng)狀態(tài)”可能是serverSocket對(duì)象已經(jīng)關(guān)閉,也可能是serverSocket對(duì)象是使用ServerSocket類的默認(rèn)構(gòu)造方法創(chuàng)建的,而且未調(diào)用bind方法綁定端口。在這里要注意的是isBound方法返回true并不意味著serverSocket對(duì)象處于活動(dòng)狀態(tài),調(diào)用close方法并不會(huì)將綁定狀態(tài)置為false。這一點(diǎn)和Socket類的isConnected方法類似。
下一篇:Java網(wǎng)絡(luò)編程從入門到精通(28):獲取ServerSocket信息的方法及FTP原理
新浪微博:http://t.sina.com.cn/androidguy 昵稱:李寧_Lining