1. 程式人生 > >Java網路程式設計(一) TCP/IP,http,socket,長連線,短連線

Java網路程式設計(一) TCP/IP,http,socket,長連線,短連線

TCP/IP

 TCP/IP是個協議組,可分為三個層次:網路層、傳輸層和應用層。
 在網路層有IP協議、ICMP協議、ARP協議、RARP協議和BOOTP協議。
 在傳輸層中有TCP協議與UDP協議。
 在應用層有:TCP包括FTP、HTTP、TELNET、SMTP等協議

                 UDP包括DNS、TFTP等協議

短連線:

連線->傳輸資料->關閉連線
   HTTP是無狀態的,瀏覽器和伺服器每進行一次HTTP操作,就建立一次連線,但任務結束就中斷連線。
   也可以這樣說:短連線是指SOCKET連線後傳送後接收完資料後馬上斷開連線。

長連線:

連線->傳輸資料->保持連線 -> 傳輸資料-> 。。。 ->關閉連線。
   長連線指建立SOCKET連線後不管是否使用都保持連線,但安全性較差。

http的長連線:

HTTP也可以建立長連線的,使用Connection:keep-alive,HTTP 1.1預設進行持久連線。HTTP1.1和HTTP1.0相比較而言,最大的區別就是增加了持久連線支援(貌
似最新的 http1.0 可以顯示的指定 keep-alive),但還是無狀態的,或者說是不可以信任的。

什麼時候用長連線,短連線?

長連線多用於操作頻繁,點對點的通訊,而且連線數不能太多情況,。每個TCP連線都需要三步握手,這需要時間,如果每個操作都是先連線,再操作的話那麼處理速度會降低很多,所以每個操作完後都不斷開,次處理時直接傳送資料包就OK了,不用建立TCP連線。例如:資料庫的連線用長連線, 如果用短連線頻繁的通訊會造成socket錯誤,而且頻繁的socket 建立也是對資源的浪費。

而像WEB網站的http服務一般都用短連結,因為長連線對於服務端來說會耗費一定的資源,而像WEB網站這麼頻繁的成千上萬甚至上億客戶端的連線用短連線會更省一些資源,如果用長連線,而且同時有成千上萬的使用者,如果每個使用者都佔用一個連線的話,那可想而知吧。所以併發量大,但每個使用者無需頻繁操作情況下需用短連好。

總之,長連線和短連線的選擇要視情況而定。

傳送接收方式

1、非同步

報文傳送和接收是分開的,相互獨立的,互不影響。這種方式又分兩種情況:

(1)非同步雙工:接收和傳送在同一個程式中,由兩個不同的子程序分別負責傳送和接收

(2)非同步單工:接收和傳送是用兩個不同的程式來完成。

2、同步

報文傳送和接收是同步進行,既報文傳送後等待接收返回報文。 同步方式一般需要考慮超時問題,即報文發出去後不能無限等待,需要設定超時時間,超過該時間傳送方不再等待讀返回報文,直接通知超時返回。

在長連線中一般是沒有條件能夠判斷讀寫什麼時候結束,所以必須要加長度報文頭。讀函式先是讀取報文頭的長度,再根據這個長度去讀相應長度的報文。

Socket是什麼

Socket是應用層與TCP/IP協議族通訊的中間軟體抽象層,它是一組介面。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket介面後面,對使用者來說,一組簡單的介面就是全部,讓Socket去組織資料,以符合指定的協議。




 主機 A 的應用程式要能和主機 B 的應用程式通訊,必須通過 Socket 建立連線,而建立 Socket 連線必須需要底層TCP/IP 協議來建立 TCP 連線。建立 TCP 連線需要底層 IP 協議來定址網路中的主機。我們知道網路層使用的 IP 協議可以幫助我們根據 IP 地址來找到目標主機,但是一臺主機上可能執行著多個應用程式,如何才能與指定的應用程式通訊就要通過 TCP 或 UPD 的地址也就是埠號來指定。這樣就可以通過一個 Socket 例項唯一代表一個主機上的一個應用程式的通訊鏈路了。

建立通訊鏈路

當客戶端要與服務端通訊,客戶端首先要建立一個 Socket 例項,作業系統將為這個 Socket 例項分配一個沒有被使用的本地埠號,並建立一個包含本地和遠端地址和埠號的套接字資料結構,這個資料結構將一直儲存在系統中直到這個連線關閉。在建立 Socket 例項的建構函式正確返回之前,將要進行 TCP 的三次握手協議,TCP 握手協議完成後,Socket例項物件將建立完成,否則將丟擲 IOException 錯誤。

與之對應的服務端將建立一個 ServerSocket 例項,ServerSocket 建立比較簡單隻要指定的埠號沒有被佔用,一般例項建立都會成功,同時作業系統也會為 ServerSocket 例項建立一個底層資料結構,這個資料結構中包含指定監聽的埠號和包含監聽地址的萬用字元,通常情況下都是“*”即監聽所有地址。之後當呼叫 accept() 方法時,將進入阻塞狀態,等待客戶端的請求。當一個新的請求到來時,將為這個連線建立一個新的套接字資料結構,該套接字資料的資訊包含的地址和埠資訊正是請求源地址和埠。這個新建立的資料結構將會關聯到 ServerSocket 例項的一個未完成的連線資料結構列表中,注意這時服務端與之對應的 Socket 例項並沒有完成建立,而要等到與客戶端的三次握手完成後,這個服務端的 Socket 例項才會返回,並將這個 Socket 例項對應的資料結構從未完成列表中移到已完成列表中。所以 ServerSocket 所關聯的列表中每個資料結構,都代表與一個客戶端的建立的 TCP 連線。

備註:

Windows 下單機最大TCP連線數

調整系統引數來調整單機的最大TCP連線數,Windows 下單機的TCP連線數有多個引數共同決定:

以下都是通過修改登錄檔[HKEY_LOCAL_MACHINE \System \CurrentControlSet \Services \Tcpip \Parameters]

1.    最大TCP連線數        TcpNumConnections

2.    TCP關閉延遲時間    TCPTimedWaitDelay    (30-240)s

3.    最大動態埠數   MaxUserPort  (Default = 5000, Max = 65534) TCP客戶端和伺服器連線時,客戶端必須分配一個動態埠,預設情況下這個動態埠的分配範圍為 1024-5000 ,也就是說預設情況下,客戶端最多可以同時發起3977 個Socket 連線

4.   最大TCB 數量   MaxFreeTcbs

系統為每個TCP 連線分配一個TCP 控制塊(TCP control block or TCB),這個控制塊用於快取TCP連線的一些引數,每個TCB需要分配 0.5 KB的pagepool 和 0.5KB 的Non-pagepool,也就說,每個TCP連線會佔用 1KB 的系統記憶體。

非Server版本,MaxFreeTcbs 的預設值為1000 (64M 以上實體記憶體)Server 版本,這個的預設值為 2000。也就是說,預設情況下,Server 版本最多同時可以建立並保持2000個TCP 連線。

5.   最大TCB Hash table 數量   MaxHashTableSize 

TCB 是通過Hash table 來管理的。

這個值指明分配 pagepool 記憶體的數量,也就是說,如果MaxFreeTcbs = 1000 , 則 pagepool 的記憶體數量為 500KB那麼 MaxHashTableSize 應大於 500 才行。這個數量越大,則Hash table 的冗餘度就越高,每次分配和查詢 TCP  連線用時就越少。這個值必須是2的冪,且最大為65536.

IBM WebSphere Voice Server windows server 2003 下的典型配置

MaxUserPort = 65534 (Decimal)

MaxHashTableSize = 65536 (Decimal)

MaxFreeTcbs = 16000 (Decimal)

這裡我們可以看到 MaxHashTableSize 被配置為比MaxFreeTcbs 大4倍,這樣可以大大增加TCP建立的速度。

參考資料: