在客戶/服務器通信模式中,客戶端需要主動創建與服務器的Socket(套接字),服務端收到了客戶端的請求,也會創建與客戶端連接的Socket。
Scoket可以看作兩端通信的收發器,服務端和客戶端都通過Scoket收發數據~~~
一:首先介紹Scoket的構造方法:
構造方法的重載:
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
1:解析:除了第一個不帶參的構造方法,其余的構造方法都試圖與服務器創建連接,如果連接成功,就返回Socket對象;如果因為某些原因連接失敗,則會拋出異常。。。。。。
2:使用無參構造方法,設定等待建立連接的超時時間:
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, 表示永遠不會超時, 默認是不會超時的.
3: 設定服務器的地址
除了第一個不帶參數的構造方法, 其他構造方法都需要在參數中設定服務器的地址, 包括服務器的IP地址或主機名, 以及端口:
Socket(InetAddress address, int port) //第一個參數address 表示主機的IP地址 Socket(String host, int port) //第一個參數host 表示主機的名字
二. 獲取Socket 的信息
在一個Socket 對象中同時包含了遠程服務器的IP 地址和端口信息, 以及客戶本地的IP 地址和端口信息. 此外, 從Socket 對象中還可以獲得輸出流和輸入流, 分別用於向服務器發送數據, 以及接收從服務器端發來的數據. 以下方法用於獲取Socket的有關信息.
getInetAddress(): 獲得遠程服務器的IP 地址. getPort(): 獲得遠程服務器的端口. getLocalAddress(): 獲得客戶本地的IP 地址. getLocalPort(): 獲得客戶本地的端口. getInputStream(): 獲得輸入流. 如果Socket 還沒有連接, 或者已經關閉, 或者已經通過 shutdownInput() 方法關閉輸入流, 那么此方法會拋出IOException. getOutputStream(): 獲得輸出流, 如果Socket 還沒有連接, 或者已經關閉, 或者已經通過 shutdownOutput() 方法關閉輸出流, 那么此方法會拋出IOException.
三. 關閉Socket
當客戶與服務器的通信結束, 應該及時關閉Socket , 以釋放Socket 占用的包括端口在內的各種資源. Socket 的 close() 方法負責關閉Socket. 當一個Socket對象被關閉, 就不能再通過它的輸入流和輸出流進行I/O操作, 否則會導致IOException.
為了確保關閉Socket 的操作總是被執行, 強烈建議把這個操作放在finally 代碼塊中:
Socket socket = null; try{ socket = new Socket(www.javathinker.org,80); //執行接收和發送數據的操作 ......... }catch(IOException e){ e.printStackTrace(); }finally{ try{ if(socket != null) socket.close(); }catch(IOException e){e.printStackTrace();} }
Socket 類提供了3 個狀態測試方法.
isClosed(): 如果Socket已經連接到遠程主機, 並且還沒有關閉, 則返回true , 否則返回false . isConnected(): 如果Socket曾經連接到遠程主機, 則返回true , 否則返回false . isBound(): 如果Socket已經與一個本地端口綁定, 則返回true , 否則返回false .
五. 設置Socket 的選項
Socket 有以下幾個選項.
TCP_NODELAY: 表示立即發送數據. SO_RESUSEADDR: 表示是否允許重用Socket 所綁定的本地地址. SO_TIMEOUT: 表示接收數據時的等待超時數據. SO_LINGER: 表示當執行Socket 的 close()方法時, 是否立即關閉底層的Socket. SO_SNFBUF: 表示發送數據的緩沖區的大小. SO_RCVBUF: 表示接收數據的緩沖區的大小. SO_KEEPALIVE: 表示對於長時間處於空閑狀態的Socket , 是否要自動把它關閉. OOBINLINE: 表示是否支持發送一個字節的TCP 緊急數據.