Socket:
在客戶/服務器通信模式中, 客戶端需要主動創建與服務器連接的 Socket(套接字), 服務器端收到了客戶端的連接請求, 也會創建與客戶連接的 Socket. Socket可看做是通信連接兩端的收發器, 服務器與客戶端都通過 Socket 來收發數據.
構造Socket
Socket的構造方法有以下幾種重載形式:
Socket()
Socket(InetAddress address, int port) throws UnknowHostException, IOException
Socket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException
Socket(String host, int port) throws UnknowHostException, IOException
Socket(String host, int port, InetAddress localAddr, int localPort) throws IOException
除了第一個不帶參數的構造方法以外, 其他構造方法都會試圖建立與服務器的連接, 如果連接成功, 就返回 Socket對象; 如果因為某些原因連接失敗, 就會拋出IOException .
1. 使用無參數構造方法, 設定等待建立連接的超時時間
Socket socket = new Socket();
SocketAddress remoteAddr = new InetSocketAddress("localhost",8000);
socket.connect(remoteAddr, 60000); //等待建立連接的超時時間為1分鐘
以上代碼用于連接到本地機器上的監聽8000端口的服務器程序, 等待連接的最長時間為1分鐘. 如果在1分鐘內連接成功則connet()方法順利返回; 如果在1分鐘內出現某種異常, 則拋出該異常; 如果超過1分鐘后, 即沒有連接成功, 也沒有出現其他異常, 那么會拋出 SocketTimeoutException. Socket 類的 connect(SocketAddress endpoint, int timeout) 方法負責連接服務器, 參數endpoint 指定服務器的地址, 參數timeout 設定超時數據, 以毫秒為單位. 如果參數timeout 設為0, 表示永遠不會超時, 默認是不會超時的.
2. 設定服務器的地址 除了第一個不帶參數的構造方法, 其他構造方法都需要在參數中設定服務器的地址, 包括服務器的IP地址或主機名, 以及端口:
Socket(InetAddress address, int port) //第一個參數address 表示主機的IP地址
Socket(String host, int port) //第一個參數host 表示主機的名字
InetAddress 類表示服務器的IP地址, InetAddress 類提供了一系列靜態工廠方法, 用于構造自身的實例, 例如:
//返回本地主機的IP地址
InetAddress addr1 = InetAddress.getLocalHost();
//返回代表 "222.34.5.7"的 IP地址
InetAddress addr2 = InetAddress.getByName("222.34.5.7");
//返回域名為"www.javathinker.org"的 IP地址
InetAddress addr3 = InetAddress.getByName("www.javathinker.org");
3. 設定客戶端的地址
在一個Socket 對象中, 即包含遠程服務器的IP 地址和端口信息, 也包含本地客戶端的IP 地址和端口信息. 默認情況下, 客戶端的IP 地址來自于客戶程序所在的主機, 客戶端的端口則由操作系統隨機分配. Socket類還有兩個構造方法允許顯式地設置客戶端的IP 地址和端口: //參數localAddr 和 localPort 用來設置客戶端的IP地址和端口
Socket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException
Socket(String host, int port, InetAddress localAddr, int localPort) throws IOException
如果一個主機同時屬于兩個以上的網絡, 它就可能擁有兩個以上的IP 地址. 例如, 一個主機在Internet 網絡中的IP 地址為 "222.67.1.34", 在一個局域網中的IP 地址為 "112.5.4.3". 假定這個主機上的客戶程序希望和同一個局域網的一個服務器程序(地址為:"112.5.4.45: 8000")通信, 客戶端可按照如下方式構造Socket 對象:
InetAddress remoteAddr1 = InetAddress.getByName("112.5.4.45");
InetAddress localAddr1 = InetAddress.getByName("112.5.4.3");
Socket socket1 = new Socket(remoteAddr1, 8000, localAddr1, 2345); //客戶端使用端口2345
4. 客戶連接服務器時可能拋出的異常當Socket 的構造方法請求連接服務器時, 可能會拋出下面的異常.
UnKnownHostException: 如果無法識別主機的名字或IP 地址, 就會拋出這種異常.
ConnectException: 如果沒有服務器進程監聽指定的端口, 或者服務器進程拒絕連接, 就會拋出這種異常. SocketTimeoutException: 如果等待連接超時, 就會拋出這種異常.
BindException: 如果無法把Socket 對象與指定的本地IP 地址或端口綁定, 就會拋出這種異常.
以上4中異常都是IOException的直接或間接子類.