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、同步
封包發送和接收是同步進行,既封包發送後等待接收傳回封包。 同步方式一般需要考慮逾時問題,即封包發出去後不能無限等待,需要設定逾時時間,超過該時間發送方不再等待讀傳回封包,直接通知逾時傳回。
在長連接配接中一般是沒有條件能夠判斷讀寫什麼時候結束,是以必須要加長度封包頭。讀函數先是讀取封包頭的長度,再根據這個長度去讀相應長度的封包。
剛接觸TCP/IP通信設計的人根據範例可以很快編出一個通信程 序,據此一些人可能會認為TCP/IP程式設計很簡單。其實不然, TCP/IP程式設計具有較為豐富的内容。其程式設計的豐富性主要展現在 通信方式和封包格式的多樣性上。
一。通信方式
主要有以下三大類:
(一)SERVER/CLIENT方式
1.一個Client方連接配接一個Server方,或稱點對點(peer to peer):
2.多個Client方連接配接一個Server方,這也是通常的并發伺服器方式。
3.一個Client方連接配接多個Server方,這種方式很少見,主要 用于一個客戶向多個伺服器發送請求情況。
(二)連接配接方式
1.長連接配接
Client方與Server方先建立通訊連接配接,連接配接建立後不斷開, 然後再進行封包發送和接收。這種方式下由于通訊連接配接一直
存在,可以用下面指令檢視連接配接是否建立:
netstat –f inet|grep 端口号(如5678)。
此種方式常用于點對點通訊。
2.短連接配接
Client方與Server每進行一次封包收發交易時才進行通訊連 接,交易完畢後立即斷開連接配接。此種方式常用于一點對多點
通訊,比如多個Client連接配接一個Server.
(三)發送接收方式
1.異步
封包發送和接收是分開的,互相獨立的,互不影響。這種方
式又分兩種情況:
(1)異步雙工:接收和發送在同一個程式中,有兩個不同的實際通信方式是這三類通信方式的組合。比如一般書上提供的 TCP/IP範例程式大都是同步短連接配接的SERVER/CLIENT程式。有的 組合是基本不用的,比較常用的有價值的組合是以下幾種:
同步短連接配接Server/Client
同步長連接配接Server/Client
異步短連接配接Server/Client
異步長連接配接雙工Server/Client
異步長連接配接單工Server/Client
其中異步長連接配接雙工是最為複雜的一種通信方式,有時候經
常會出現在不同銀行或不同城市之間的兩套系統之間的通信。 比如金卡工程。由于這幾種通信方式比較固定,是以可以預
先編制這幾種通信方式的模闆程式。
二.封包格式
通信封包格式多樣性更多,相應地就必須設計對應的讀寫封包的接 收和發送封包函數。
(一)阻塞與非阻塞方式
1.非阻塞方式
讀函數不停地進行讀動作,如果沒有封包接收到,等待一段時間後 逾時傳回,這種情況一般需要指定逾時時間。
2.阻塞方式
如果沒有封包接收到,則讀函數一直處于等待狀态,直到有封包到達。
(二)循環讀寫方式
1.一次直接讀寫封包
在一次接收或發送封包動作中一次性不加分别地全部讀取或全部 發送封包位元組。
2.不指定長度循環讀寫
這一般發生在短連接配接程序中,受網絡路由等限制,一次較長的報 文可能在網絡傳輸過程中被分解成了好幾個包。一次讀取可能不 能全部讀完一次封包,這就需要循環讀封包,直到讀完為止。
3.帶長度封包頭循環讀寫
這種情況一般是在長連接配接程序中,由于在長連接配接中沒有條件能夠 判斷循環讀寫什麼時候結束,是以必須要加長度封包頭。讀函數 先是讀取封包頭的長度,再根據這個長度去讀封包.實際情況中, 報頭的碼制格式還經常不一樣,如果是非ASCII碼的封包頭,還必須 轉換成ASCII,常見的封包頭碼制有:
(1)n個位元組的ASCII碼
(2)n個位元組的BCD碼
(3)n個位元組的網絡整型碼
以上是幾種比較典型的讀寫封包方式,可以與通信方式模闆一起 預先提供一些典型的API讀寫函數。當然在實際問題中,可能還 必須編寫與對方封包格式配套的讀寫API.
在實際情況中,往往需要把我們自己的系統與别人的系統進行連接配接, 有了以上模闆與API,可以說連接配接任何方式的通信程式都不存在問題。
- TCP連接配接
當網絡通信時采用TCP協定時,在真正的讀寫操作之前,server與client之間必須建立一個連接配接,當讀寫操作完成後,雙方不再需要這個連接配接時它們可以釋放這個連接配接,連接配接的建立是需要三次握手的,而釋放則需要4次握手,是以說每個連接配接的建立都是需要資源消耗和時間消耗的
經典的三次握手示意圖:
經典的四次握手關閉圖:
- TCP短連接配接
我們模拟一下TCP短連接配接的情況,client向server發起連接配接請求,server接到請求,然後雙方建立連接配接。client向server發送消息,server回應client,然後一次讀寫就完成了,這時候雙方任何一個都可以發起close操作,不過一般都是client先發起close操作。為什麼呢,一般的server不會回複完client後立即關閉連接配接的,當然不排除有特殊的情況。從上面的描述看,短連接配接一般隻會在client/server間傳遞一次讀寫操作
短連接配接的優點是:管理起來比較簡單,存在的連接配接都是有用的連接配接,不需要額外的控制手段
3.TCP長連接配接
接下來我們再模拟一下長連接配接的情況,client向server發起連接配接,server接受client連接配接,雙方建立連接配接。Client與server完成一次讀寫之後,它們之間的連接配接并不會主動關閉,後續的讀寫操作會繼續使用這個連接配接。
首先說一下TCP/IP詳解上講到的TCP保活功能,保活功能主要為伺服器應用提供,伺服器應用希望知道客戶主機是否崩潰,進而可以代表客戶使用資源。如果客戶已經消失,使得伺服器上保留一個半開放的連接配接,而伺服器又在等待來自用戶端的資料,則伺服器将應遠等待用戶端的資料,保活功能就是試圖在伺服器端檢測到這種半開放的連接配接。
如果一個給定的連接配接在兩小時内沒有任何的動作,則伺服器就向客戶發一個探測封包段,客戶主機必須處于以下4個狀态之一:
客戶主機依然正常運作,并從伺服器可達。客戶的TCP響應正常,而伺服器也知道對方是正常的,伺服器在兩小時後将保活定時器複位。
客戶主機已經崩潰,并且關閉或者正在重新啟動。在任何一種情況下,客戶的TCP都沒有響應。服務端将不能收到對探測的響應,并在75秒後逾時。伺服器總共發送10個這樣的探測 ,每個間隔75秒。如果伺服器沒有收到一個響應,它就認為客戶主機已經關閉并終止連接配接。
客戶主機崩潰并已經重新啟動。伺服器将收到一個對其保活探測的響應,這個響應是一個複位,使得伺服器終止這個連接配接。
客戶機正常運作,但是伺服器不可達,這種情況與2類似,TCP能發現的就是沒有收到探查的響應。
從上面可以看出,TCP保活功能主要為探測長連接配接的存活狀況,不過這裡存在一個問題,存活功能的探測周期太長,還有就是它隻是探測TCP連接配接的存活,屬于比較斯文的做法,遇到惡意的連接配接時,保活功能就不夠使了。
在長連接配接的應用場景下,client端一般不會主動關閉它們之間的連接配接,Client與server之間的連接配接如果一直不關閉的話,會存在一個問題,随着用戶端連接配接越來越多,server早晚有扛不住的時候,這時候server端需要采取一些政策,如關閉一些長時間沒有讀寫事件發生的連接配接,這樣可以避免一些惡意連接配接導緻server端服務受損;如果條件再允許就可以以用戶端機器為顆粒度,限制每個用戶端的最大長連接配接數,這樣可以完全避免某個蛋疼的用戶端連累後端服務。
長連接配接和短連接配接的産生在于client和server采取的關閉政策,具體的應用場景采用具體的政策,沒有十全十美的選擇,隻有合适的選擇。
參考:
- TCP/IP詳解 卷一
轉自:
http://www.cnblogs.com/beifei/archive/2011/06/26/2090611.html