Java中基於TCP/IP的網路程序設計主要由以下幾個類來實現,
1,,InetAdderss,主要的作用是設置IP地址,該類有若干個構造函數,以及一些靜態的方法,詳細的信息可見JDK參考文檔,比較常用的幾個方法如下,
public String getHostAdderss();
public synchronized static InetAdderss getLocalHost();
public static InetAddress getByName(String host);
以上方法會拋出UnknownHostException
2,,,ServerSocekt,主要用於服務器端得程序設計中,首先建立一個ServerSocket類的對象,該類有若干個構造函數,
如下:
public ServerSocket(int port);
public ServerSocket(int port,int backlog);
public ServerSocket(int port,int backlog,InetAdderss bindAddr);
以上方法會拋出IOException異常
當建立起了服務器端的監聽套接字之後就可以調用socket的accept方法來接受連接的請求,該方法會返回一個Socket對象代表與客戶機端進行通信的套接字,
3,,,Socket,,主要用於客戶端,用來與服務器端進行通信,也用於服務器端,用來接受服務器端調用accept返回的套接字,與客戶機進行通信,該類的構造方法主要有以下幾個重載的方法
public Socket();
public Socket(InetAddress address,int port);
public Socket(InetAddress address,int port,InetAddress localAddress,int port);
public Socket(String host,int port);
public Socket(String host,int port,InetAddress local,int localport);
以上方法都會拋出IOException異常,除了第一個方法之外都會主動的與服務器進行連接,
該類還可以設置以下幾個方法
3.1設置連接等待時間
可以設置連接的等待時間,如果在等待時間到達後仍然沒有連接成功則拋出異常用法如下
Socket socket=new Socket();
SocketAddress remoteAddr=new InetAddress("localhost",8000);
socket.connect(remoteAddr,60000);//等待1分鐘,如果在一分鐘內沒有連接成功則拋出SocketTimeOutException異常
3.2獲取Socket的信息
可以調用getInetAddress()來獲取遠程服務器的IP地址等信息,
調用getInputStream()來獲取輸入流
調用getOutputStream()來獲取輸出流
調用getLocalPort()來獲取本地的端口
調用getLocalHost()來獲取本地的IP地址
3.3關閉Socket
當客戶機與服務器通信終結的時候應該調用socket的close方法來關閉socket,以釋放socekt佔用的各種資源
同時socket提供了幾個方法來測試socket是否已經關閉,如isClosed(),isConnect(),isBound()等,
3。4
當通過socket通信的時候如何判斷對方已經關閉了?可以有以下幾種方式來進行判斷
1,以約定的特殊字符來作爲通信結束的標誌,如bye
2,進程A首先發送一個消息告訴B,其所發送的正文的長度,再發送正文
3,當A發送完所用的數據,關閉socket後當進程B再次執行到read()方法的時候會返回-1,若執行bufferedreader的readline方法的時候回返回null
4,當調用socket的close方法時會關閉其輸入輸出流,有時候僅僅希望關閉輸入輸出流其中之一,此時可以採用socket提供的半關閉方法,shutdownInput()關閉輸入流, 或者shutdownOutput()關閉輸出流,
總之在發送方沒有關閉socket的情況下突然就結束了運行,則接收方在執行到readline方法的時候會跑出SocketException :connection reset異常,若發送方先關閉socket或者輸出流後再結束運行,那麼接收方的readline會讀到null,read會返回-1;
4,,Socket的若干個選項
Socket有若干個選項,來控制Socket的各種行爲
4.1 TCP_NODELAY,,是否立即發送數據
可以通過setTcpNoDelay(boolean on)來設置,在默認情況下該值爲false,表示採用緩衝的方式來進行通信,適用於發送方要發送大批的數據,且接收方會及時的作出迴應的場合,
4.2, SO_RESUSEADDR 用來設置端口是否立即可用
可以用setResuseAddress(boolean on)方法來設置
一般接收方通過socket的close方法關閉socket時候,若網路還有數據傳送到該socket,則底層的socket不會立即的釋放掉本地端口,而是等待一段時間之後,確保接收到網路上發過來的數據後在釋放端口,默認值爲false,,可以採用set方法來設置該值來表示同一主機上的其他進程可以立即的重用該端口
4.3 SO_TIMEOUT 用來設置超時的時間
setSoTimeout(int milliseconds);
如下,byte[] buff=new byte[1024];'
in.read(buff);
若流中有1024個字節,read方法會等待這些數據讀入buffer中後返回讀取的字節數
若已經快要到流的結尾的時候,read會將這些字節讀入buffer中返回讀取的字節數
若已經到流的結尾的時候,會返回-1
若連接已經斷開則會拋出IOException異常
若設置了setTimeout等待時間,這超出這一時間後會拋出SocketTimeoutException異常,當拋出異常後Socekt依然可用,可以嘗試再次的連接,
4.4 SO_LINGER
setSoLinger(boolean on,int seconds);用來控制Socket的默認行爲
默認的情況下執行socket的close方法時候會立即的返回,但是底層的socket並沒有關閉,而是延遲一段時間後直到所有的剩餘數據發送完,若執行了setSoLinger(true,0),則執行完socket的close方法時會立即返回,且底層的socket會立即關閉,廢棄未發完的數據,
4.5 SO_RCVBUF 用於設置輸入的數據的緩衝區大小
void setRecvBufferSize(int size);
4.6 SO_SNDBUF 用於輸出的數據緩衝區的大小
void setSendBufferSize(int size)
4.7 SO_KEEPALIVE 標示連接是否有效
當該選項爲true時,標示底層的TCP實現會監視該連接是否有效,當處於空閒的連接狀態持續兩個小時的時候本地的socket會發送一個數據包給遠程的socekt,若遠程的socket沒有迴應則,本地的socekt會持續嘗試11分鐘,直到接收到響應爲止,若在12分鐘內無響應,則tcp實現會自動的關閉本地的socket,斷開連接,該選項的默認值爲false,標示不會監視tcp連接的有效性,,,