java 中的socket_Java中Socket用法详解
一、構造Socket
Socket的構造方法有以下幾種重載形式:
(1)Socket()
(2)Socket(InetAddress address, int port)throws UnknownHostException,IOException
(3)Socket(InetAddress address, int port, InetAddress localAddr, int localPort)throws IOException
(4)Socket(String host, int port) throws UnknownHostException,IOException
(5)Socket(String host, int port, InetAddress localAddr, int localPort) throws IOException
各構造方法的用法如下:
1. 設定等待建立連接的超時時間:
Socket socket=new Socket();SocketAddress remoteAddr=new InetSocketAddress(“localhost”,8000);//等待建立連接的超時時間為1分鐘
socket.connect(remoteAddr, 60000);
2. 設定服務器的地址:
Socket(InetAddress address, int port)
Socket(String host, int port)
InetAddress類表示IP地址,其用法如下://返回本地主機的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地址和端口:
Socket(InetAddress address, int port, InetAddress localAddr, int localPort)throws IOExceptionSocket(String host, int port, InetAddress localAddr, int localPort) throws IOException
4. 客戶連接服務器時可能拋出的異常:
當Socket的構造方法請求連接服務器時,可能會拋出以下異常:
l UnknownHostException:如果無法識別主機的名字或IP地址,就會拋出這種異常。
l ConnectException:如果沒有服務器進程監聽指定的端口,或者服務器進程拒絕連接,就會拋出這種異常。
l SocketTimeoutException:如果等待連接超時,就會拋出這種異常。
l BindException:如果無法把Socket對象與指定的本地IP地址或端口綁定,就會拋出這種異常。
二、獲取Socket的信息
以下方法用于獲取Socket的有關信息:
l getInetAddress():獲得遠程服務器的IP地址。
l getPort():獲得遠程服務器的端口。
l getLocalAddress():獲得客戶本地的IP地址。
l getLocalPort():獲得客戶本地的端口。
l getInputStream():獲得輸入流。如果Socket還沒有連接,或者已經關閉,或者已經通過shutdownInput()方法關閉輸入流,那么此方法會拋出IOException。
l getOutputStream():獲得輸出流。如果Socket還沒有連接,或者已經關閉,或者已經通過shutdownOutput()方法關閉輸出流,那么此方法會拋出IOException。
三、關閉Socket
1. 當客戶與服務器的通信結束,應該及時關閉Socket,以釋放Socket占用的包括端口在內的各種資源。Socket的close()方法負責關閉Socket。推薦代碼如下:
Socket socket=null;try{socket=newSocket(“www.javathinker.org”,80);
//執行接收和發送數據的操作
…
}catch(IOException e){
e.printStackTrace();
}finally{
try{
if(socket!=null)socket.close();
}catch(IOException e){e.printStackTrace();}
}
2. Socket類提供了三個狀態測試方法:
l isClosed()
l isConnected()
l isBound()
3. 如果要判斷一個Socket對象當前是否處于連接狀態,可采用以下方式:
boolean isConnected=socket.isConnected() && !socket.isClosed();
四、半關閉Socket
1. 有的時候,可能僅僅希望關閉輸出流或輸入流之一。此時可以采用Socket類提供的半關閉方法:
l shutdownInput():關閉輸入流。
l shutdownOutput(): 關閉輸出流。
2. 先后調用Socket的shutdownInput()和shutdownOutput()方法,僅僅關閉了輸入流和輸出流,并不等價于調用Socket的close()方法。在通信結束后,仍然要調用Socket的close()方法,因為只有該方法才會釋放Socket占用的資源,比如占用的本地端口等。
3. Socket類還提供了兩個狀態測試方法,用來判斷輸入流和輸出流是否關閉:
l public boolean isInputShutdown()
l public boolean isOutputShutdown()
五、設置Socket的選項
Socket有以下幾個選項:
n TCP_NODELAY:表示立即發送數據。
n SO_RESUSEADDR:表示是否允許重用Socket所綁定的本地地址。
n SO_TIMEOUT:表示接收數據時的等待超時時間。
n SO_LINGER:表示當執行Socket的close()方法時,是否立即關閉底層的Socket。
n SO_SNFBUF:表示發送數據的緩沖區的大小。
n SO_RCVBUF:表示接收數據的緩沖區的大小。
n SO_KEEPALIVE:表示對于長時間處于空閑狀態的Socket,是否要自動把它關閉。
n OOBINLINE:表示是否支持發送一個字節的TCP緊急數據。
1. TCP_NODELAY選項
1) 設置該選項:public void setTcpNoDelay(boolean on) throws SocketException
2) 讀取該選項:public boolean getTcpNoDelay() throws SocketException
3) TCP_NODEALY的默認值為false,表示采用Negale算法。如果調用setTcpNoDelay(true)方法,就會關閉Socket的緩沖,確保數據及時發送:
if(!socket.getTcpNoDelay()) socket.setTcpNoDelay(true);
4) 如果Socket的底層實現不支持TCP_NODELAY選項,那么getTcpNoDelay()和setTcpNoDelay()方法會拋出SocketException。
2. SO_RESUSEADDR選項
1) 設置該選項:public void setResuseAddress(boolean on) throws SocketException
2) 讀取該選項:public boolean getResuseAddress() throws SocketException
3) 為了確保一個進程關閉了Socket后,即使它還沒釋放端口,同一個主機上的其他進程還可以立刻重用該端口,可以調用Socket的setResuseAddress(true)方法:
if(!socket.getResuseAddress()) socket.setResuseAddress(true);
4) 值得注意的是socket.setResuseAddress(true)方法必須在Socket還沒有綁定到一個本地端口之前調用,否則執行socket.setResuseAddress(true)方法無效。因此必須按照以下方式創建Socket對象,然后再連接遠程服務器:
Socket socket = newSocket(); //此時Socket對象未綁定到本地端口,并且未連接遠程服務器socket.setResuseAddress(true);SocketAddress remoteAddr = newInetSocketAddress(“remotehost”,8000);
socket.connect(remoteAddr);//連接遠程服務器,并且綁定匿名的本地端口
或者:
Socket socket = newSocket(); //此時Socket對象未綁定到本地端口,并且未連接遠程服務器
socket.setResuseAddress(true);
SocketAddress localAddr = newInetSocketAddress(“localhost”,9000);
SocketAddress remoteAddr = newInetSocketAddress(“remotehost”,8000);
socket.bind(localAddr); //與本地端口綁定
socket.connect(remoteAddr); //連接遠程服務器,并且綁定匿名的本地端口
3. SO_TIMEOUT選項
1) 設置該選項:public void setSoTimeout(int milliseconds) throws SocketException
2) 讀取該選項:public int getSoTimeOut() throws SocketException
3) 當通過Socket的輸入流讀數據時,如果還沒有數據,就會等待。Socket類的SO_TIMEOUT選項用于設定接收數據的等待超時時間,單位為毫秒,它的默認值為0,表示會無限等待,永遠不會超時。
4) Socket的setSoTimeout()方法必須在接收數據之前執行才有效。此外,當輸入流的read()方法拋出SocketTimeoutException后,Socket仍然是連接的,可以嘗試再次讀取數據。
4. SO_LINGER選項
1) 設置該選項:public void setSoLinger(boolean on, int seconds) throws SocketException
2) 讀取該選項:public int getSoLinger() throws SocketException
3) SO_LINGER選項用來控制Socket關閉時的行為。
l socket.setSoLinger(true,0):執行Socket的close()方法時,該方法也會立即返回,但底層的Socket也會立即關閉,所有未發送完的剩余數據被丟棄。
l socket.setSoLinger(true,3600):執行Socket的close()方法時,該方法不會立即返回,而進入阻塞狀態,同時,底層的Socket會嘗試發送剩余的數據。只有滿足以下兩個條件之一,close()方法才返回:
n 底層的Socket已經發送完所有的剩余數據。
n 盡管底層的Socket還沒有發送完所有的剩余數據,但已經阻塞了3600秒。close()方法的阻塞時間超過3600秒,也會返回,剩余未發送的數據被丟棄。
以上兩種情況內,當close()方法返回后,底層的Socket會被關閉,斷開連接。
4) setSoLinger(boolean on ,int second)方法中的seconds參數以秒為單位,而不是以毫秒為單位。
5. SO_RCVBUF選項
1) 設置該選項:public void setReceiveBufferSize(int size) throws SocketException
2) 讀取該選項:public int getReceiveBufferSize() throws SocketException
3) SO_RCVBUF表示Socket的用于輸入數據的緩沖區的大小。
4) 如果底層Socket不支持SO_RCVBUF選項,那么setReceiveBufferSize()方法會拋出SocketException。
總結
以上是生活随笔為你收集整理的java 中的socket_Java中Socket用法详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 台达变频器485通讯接线图_台达变频器基
- 下一篇: 来讲讲新生代剪辑工具,人工智能视频剪辑软