天天看點

Java網絡程式設計從入門到精通(27):關閉服務端連接配接

本文為原創,如需轉載,請注明作者和出處,謝謝!

    在用戶端和服務端的資料互動完成後,一般需要關閉網絡連接配接。對于服務端來說,需要關閉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

        ServerSocket serverSocket = new ServerSocket(1234);

        while (true)

        {

            Socket socket = serverSocket.accept();

            socket.close();           

        }

  測試

執行下面的指令

java server.CloseSocket

java server.Client

運作結果

read() = -1

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)

顯式地調用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處于非活動狀态!");

上面代碼所示的“非活動狀态”可能是serverSocket對象已經關閉,也可能是serverSocket對象是使用ServerSocket類的預設構造方法建立的,而且未調用bind方法綁定端口。在這裡要注意的是isBound方法傳回true并不意味着serverSocket對象處于活動狀态,調用close方法并不會将綁定狀态置為false。這一點和Socket類的isConnected方法類似。

<a href="http://www.eoeandroid.com/forumdisplay.php?fid=4">國内最棒的Google Android技術社群(eoeandroid),歡迎通路!</a>

繼續閱讀