JAVASocket超時淺析_第1頁
JAVASocket超時淺析_第2頁
JAVASocket超時淺析_第3頁
JAVASocket超時淺析_第4頁
JAVASocket超時淺析_第5頁
已閱讀5頁,還剩8頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、 JAVA Socket超時淺析  套接字或插座(socket)是一種軟件形式的抽象,用于表達兩臺機器間一個連接的“終端”。針對一個特定的連接,每臺機器上都有一個“套接字”,可以想象它們之間有一條虛擬的“線纜”。JAVA有兩個基于數據流的套接字類:ServerSocket,服務器用它“偵聽”進入的連接;Socket,客戶端用它初始一次連接。偵聽套接字只能接收新的連接請求,不能接收實際的數據包。  套接字是基于TCP/IP實現的,它是用來提供一個訪問TCP的服務接口,或者說套接字socket是TCP的應用編程接口API,通過它應用層就可以訪問TCP提供的服務。在JA

2、VA中,我們用ServerSocket、Socket類創建一個套接字連接,從套接字得到的結果是一個InputStream以及OutputStream對象,以便將連接作為一個IO流對象對待。通過IO流可以從流中讀取數據或者寫數據到流中,讀寫IO流會有異常IOException產生。  套接字底層是基于TCP的,所以socket的超時和TCP超時是相同的。下面先討論套接字讀寫緩沖區,接著討論連接建立超時、讀寫超時以及JAVA套接字編程的嵌套異常捕獲和一個超時例子程序的抓包示例。 1 socket讀寫緩沖區  一旦創建了一個套接字實例,操作系統就會為其分配緩沖區以存放接

3、收和要發送的數據。    JAVA可以設置讀寫緩沖區的大小-setReceiveBufferSize(int size), setSendBufferSize(int size)。  向輸出流寫數據并不意味著數據實際上已經被發送,它們只是被復制到了發送緩沖區隊列SendQ,就是在Socket的OutputStream上調用flush()方法,也不能保證數據能夠立即發送到網絡。真正的數據發送是由操作系統的TCP協議棧模塊從緩沖區中取數據發送到網絡來完成的。  當有數據從網絡來到時,TCP協議棧模塊接收數據并放入接收緩沖區隊列RecvQ,輸入流In

4、putStream通過read方法從RecvQ中取出數據。 2 socket連接建立超時  socket連接建立是基于TCP的連接建立過程。TCP的連接需要通過3次握手報文來完成,開始建立TCP連接時需要發送同步SYN報文,然后等待確認報文SYN+ACK,最后再發送確認報文ACK。TCP連接的關閉通過4次揮手來完成,主動關閉TCP連接的一方發送FIN報文,等待對方的確認報文;被動關閉的一方也發送FIN報文,然等待確認報文。  正在等待TCP連接請求的一端有一個固定長度的連接隊列,該隊列中的連接已經被TCP接受(即三次握手已經完成),但還沒有被應用層所接受。TCP接

5、受一個連接是將其放入這個連接隊列,而應用層接受連接是將其從該隊列中移出。應用層可以通過設置backlog變量來指明該連接隊列的最大長度,即已被TCP接受而等待應用層接受的最大連接數。  當一個連接請求SYN到達時,TCP確定是否接受這個連接。如果隊列中還有空間,TCP模塊將對SYN進行確認并完成連接的建立。但應用層只有在三次握手中的第三個報文收到后才會知道這個新連接。如果隊列沒有空間,TCP將不理會收到的SYN。  如果應用層不能及時接受已被TCP接受的連接,這些連接可能占滿整個連接隊列,新的連接請求可能不被響應而會超時。如果一個連接請求SYN發送后,一段時間后沒有收到確認

6、SYN+ACK,TCP會重傳這個連接請求SYN兩次,每次重傳的時間間隔加倍,在規定的時間內仍沒有收到SYN+ACK,TCP將放棄這個連接請求,連接建立就超時了。  JAVA Socket連接建立超時和TCP是相同的,如果TCP建立連接時三次握手超時,那么導致Socket連接建立也就超時了。可以設置Socket連接建立的超時時間-connect(SocketAddress endpoint, int timeout)如果在timeout內,連接沒有建立成功,在TimeoutException異常被拋出。如果timeout的值小于三次握手的時間,那么Socket連接永遠也不會建立。

7、60; 不同的應用層有不同的連接建立過程,Socket的連接建立和TCP一樣-僅僅需要三次握手就完成連接,但有些應用程序需要交互很多信息后才能成功建立連接,比如Telnet協議,在TCP三次握手完成后,需要進行選項協商之后,Telnet連接才建立完成。 3 socket讀超時  如果輸入緩沖隊列RecvQ中沒有數據,read操作會一直阻塞而掛起線程,直到有新的數據到來或者有異常產生。調用setSoTimeout(int timeout)可以設置超時時間,如果到了超時時間仍沒有數據,read會拋出一個SocketTimeoutException,程序需要捕獲這個異常,但是當前

8、的socket連接仍然是有效的。  如果對方進程崩潰、對方機器突然重啟、網絡斷開,本端的read會一直阻塞下去,這時設置超時時間是非常重要的,否則調用read的線程會一直掛起。  TCP模塊把接收到的數據放入RecvQ中,直到應用層調用輸入流的read方法來讀取。如果RecvQ隊列被填滿了,這時TCP會根據滑動窗口機制通知對方不要繼續發送數據,本端停止接收從對端發送來的數據,直到接收者應用程序調用輸入流的read方法后騰出了空間。 4 socket寫超時  socket的寫超時是基于TCP的超時重傳。超時重傳是TCP保證數據可靠性傳輸的一個重要機制,其原

9、理是在發送一個數據報文后就開啟一個計時器,在一定時間內如果沒有得到發送報文的確認ACK,那么就重新發送報文。如果重新發送多次之后,仍沒有確認報文,就發送一個復位報文RST,然后關閉TCP連接。首次數據報文發送與復位報文傳輸之間的時間差大約為9分鐘,也就是說如果9分鐘內沒有得到確認報文,就關閉連接。但是這個值是根據不同的TCP協議棧實現而不同。  如果發送端調用write持續地寫出數據,直到SendQ隊列被填滿。如果在SendQ隊列已滿時調用write方法,則write將被阻塞,直到SendQ有新的空閑空間為止,也就是說直到一些字節傳輸到了接收者套接字的RecvQ中。如果此時RecvQ

10、隊列也已經被填滿,所有操作都將停止,直到接收端調用read方法將一些字節傳輸到應用程序。  當Socket的write發送數據時,如果網線斷開、對端進程崩潰或者對端機器重啟動,TCP模塊會重傳數據,最后超時而關閉連接。下次如再調用write會導致一個異常而退出。  Socket寫超時是基于TCP協議棧的超時重傳機制,一般不需要設置write的超時時間,也沒有提供這種方法。 5 雙重嵌套異常捕獲   如果ServerSocket、Socket構造失敗,只需要僅僅捕獲這個構造失敗異常而不需要調用套接字的close方法來釋放資源(必須保證構造失敗后不

11、會留下任何需要清除的資源),因為這時套接字內部資源沒有被成功分配。如果構造成功,必須進入一個try finally語句塊里調用close釋放套接字。請參照下面例子程序。java view plaincopy1. import .*;  2. import java.io.*;  3. public class SocketClientTest  4.   5.   public static final int PO

12、RT = 8088;  6.   public static void main( String args ) throws Exception  7.     8.     InetAddress addr = InetAddress.getByName( "127.0.0.1" );&

13、#160; 9.     Socket socket = new Socket();  10.     try  11.       12.       socket.connect( new InetSocketAddress( addr, PORT ),&

14、#160;30000 );  13.       socket.setSendBufferSize(100);  14.         15.       BufferedWriter out = new BufferedWriter( new OutputStreamWriter(&#

15、160;socket.getOutputStream() ) );  16.       int i = 0;  17.         18.       while( true )  19.       &

16、#160; 20.         System.out.println( "client sent - hello * " + i+ );  21.         out.write( "client sent - hello *

17、60;" + i );  22.         out.flush();  23.           24.         Thread.sleep( 1000 );  25.    

18、     26.       27.     finally  28.       29.       socket.close();  30.       31.     32. 

19、0;  java view plaincopy1. import java.io.*;  2. import .ServerSocket;  3. import .Socket;  4. public class SocketServerTest  5.   6.   public static final int PORT = 8088;

20、0; 7.   public static final int BACKLOG = 2;  8.   public static void main( String args ) throws IOException  9.     10.     ServerSocket se

21、rver = new ServerSocket( PORT, BACKLOG );  11.     System.out.println("started: " + server);  12.     try  13.       14.     

22、  Socket socket = server.accept();  15.       try  16.         17.         BufferedReader in = new BufferedReader( new&#

23、160;InputStreamReader( socket.getInputStream() ) );  18.         String info = null;  19.           20.         while(&#

24、160;( info = in.readLine() ) != null )  21.           22.           System.out.println( info );  23.      

25、0;    24.         25.       finally  26.         27.         socket.close();  28.     

26、0;   29.       30.     finally  31.       32.       server.close();  33.       34.     35.   &#

27、160;  執行上面的程序,在程序運行一會兒之后,斷開client和server之間的網絡連接,在機器上輸出如下: Server上的輸出:Echoing:client sent -hello0 Echoing:client sent -hello1Echoing:client sent -hello2Echoing:client sent -hello3Echoing:client sent -hello4Echoing:client sent -hello5Echoing:client sent -hello6 ->> 斷開了網絡連接之后沒

28、有數據輸出 Client上的輸出:socket default timeout = 0socket = Socketaddr=/10.15.9.99,port=8088,localport=4691begin to readclient sent - hello * 0client sent - hello * 1client sent - hello * 2client sent - hello * 3client sent - hello * 4client sent - hello * 5client sent - hello * 6client sent - hello *

29、7client sent - hello * 8  client sent - hello * 9client sent - hello * 10  ->> 斷開網絡連接后客戶端進程掛起 .SocketException : Connection reset by peer: socket write error    at .SocketOutputStream.socketWrite0( Native Method )    at .SocketOutputStream.socketWrite( SocketOutputSt

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論