轉。。。。。。。。
SOCKET,TCP/UDP,HTTP,FTP
(一)TCP/UDP,SOCKET,HTTP,FTP簡析
TCP/IP是個協(xié)議組,可分為三個層次:網(wǎng)絡層、傳輸層和應用層:
網(wǎng)絡層:IP協(xié)議、ICMP協(xié)議、ARP協(xié)議、RARP協(xié)議和BOOTP協(xié)議
傳輸層:TCP協(xié)議與UDP協(xié)議
應用層:FTP、HTTP、TELNET、SMTP、DNS等協(xié)議
HTTP是應用層協(xié)議,其傳輸都是被包裝成TCP協(xié)議傳輸??梢杂肧OCKET實現(xiàn)HTTP。
SOCKET是實現(xiàn)傳輸層協(xié)議的一種編程API,可以是TCP,也可以是UDP。
(二)Socket連接與HTTP連接區(qū)別
【Socket】
由于通常情況下Socket連接就是TCP連接,因此Socket連接一旦建立,通信雙方即可開始相互發(fā)送數(shù)據(jù)內容,直到雙方連接斷開。但在實際網(wǎng)絡應用中,客戶端到服務器之間的通信往往需要穿越多個中間節(jié)點,例如路由器、網(wǎng)關、防火墻等,大部分防火墻默認會關閉長時間處于非活躍狀態(tài)的連接而導致 Socket 連接斷連,因此需要通過輪詢告訴網(wǎng)絡,該連接處于活躍狀態(tài)。
【Http】
HTTP協(xié)議是建立在TCP協(xié)議之上的一種應用,HTTP連接使用的是“請求—響應”的方式,不僅在請求時需要先建立連接,而且需要客戶端向服務器發(fā)出請求后,服務器端才能回復數(shù)據(jù)。在請求結束后,會主動釋放連接。從建立連接到關閉連接的過程稱為“一次連接”。由于HTTP在每次請求結束后都會主動釋放連接,因此HTTP連接是一種“短連接”,要保持客戶端程序的在線狀態(tài),需要不斷地向服務器發(fā)起連接請求。通常的做法是即時不需要獲得任何數(shù)據(jù),客戶端也保持每隔一段固定的時間向服務器發(fā)送一次“保持連接”的請求,服務器在收到該請求后對客戶端進行回復,表明知道客戶端“在線”。若服務器長時間無法收到客戶端的請求,則認為客戶端“下線”,若客戶端長時間無法收到服務器的回復,則認為網(wǎng)絡已經(jīng)斷開。
HTTP協(xié)議是建立在請求/響應模型上的。首先由客戶建立一條與服務器的TCP鏈接,并發(fā)送一個請求到服務器,請求中包含請求方法、URI、協(xié)議版本以及相關的MIME樣式的消息。服務器響應一個狀態(tài)行,包含消息的協(xié)議版本、一個成功和失敗碼以及相關的MIME式樣的消息。
【適用情況】
很多情況下,需要服務器端主動向客戶端推送數(shù)據(jù),保持客戶端與服務器數(shù)據(jù)的實時與同步。此時若雙方建立的是Socket連接,服務器就可以直接將數(shù)據(jù)傳送給客戶端;
若雙方建立的是HTTP連接,則服務器需要等到客戶端發(fā)送一次請求后才能將數(shù)據(jù)傳回給客戶端,因此,客戶端定時向服務器端發(fā)送連接請求,不僅可以保持在線,同時也是在“詢問”服務器是否有新的數(shù)據(jù),如果有就將數(shù)據(jù)傳給客戶端。
【SOCKET原理】
(1)套接字(socket)概念:
套接字(socket)是通信的基石,是支持TCP/IP協(xié)議的網(wǎng)絡通信的基本操作單元。它是網(wǎng)絡通信過程中端點的抽象表示,包含進行網(wǎng)絡通信必須的五種信息:連接使用的協(xié)議,本地主機的IP地址,本地進程的協(xié)議端口,遠地主機的IP地址,遠地進程的協(xié)議端口。
應用層通過傳輸層進行數(shù)據(jù)通信時,TCP會遇到同時為多個應用程序進程提供并發(fā)服務的問題。多個TCP連接或多個應用程序進程可能需要通過同一個 TCP協(xié)議端口傳輸數(shù)據(jù)。為了區(qū)別不同的應用程序進程和連接,許多計算機操作系統(tǒng)為應用程序與TCP/IP協(xié)議交互提供了套接字(Socket)接口。應用層可以和傳輸層通過Socket接口,區(qū)分來自不同應用程序進程或網(wǎng)絡連接的通信,實現(xiàn)數(shù)據(jù)傳輸?shù)牟l(fā)服務。
(2)建立socket連接:
建立Socket連接至少需要一對套接字,其中一個運行于客戶端,稱為ClientSocket ,另一個運行于服務器端,稱為ServerSocket 。
套接字之間的連接過程分為三個步驟:服務器監(jiān)聽,客戶端請求,連接確認。
服務器監(jiān)聽:服務器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態(tài),實時監(jiān)控網(wǎng)絡狀態(tài),等待客戶端的連接請求
客戶端請求:指客戶端的套接字提出連接請求,要連接的目標是服務器端的套接字。為此,客戶端的套接字必須首先描述它要連接的服務器的套接字,指出服務器端套接字的地址和端口號,然后就向服務器端套接字提出連接請求。
連接確認:當服務器端套接字監(jiān)聽到或者說接收到客戶端套接字的連接請求時,就響應客戶端套接字的請求,建立一個新的線程,把服務器端套接字的描述發(fā)給客戶端,一旦客戶端確認了此描述,雙方就正式建立連接。而服務器端套接字繼續(xù)處于監(jiān)聽狀態(tài),繼續(xù)接收其他客戶端套接字的連接請求。
(3)SOCKET連接與TCP連接
創(chuàng)建Socket連接時,可以指定使用的傳輸層協(xié)議,Socket可以支持不同的傳輸層協(xié)議(TCP或UDP),當使用TCP協(xié)議進行連接時,該Socket連接就是一個TCP連接。
(三)TCP 與 UDP
【概念】
TCP --- 傳輸控制協(xié)議,提供的是面向連接、可靠的字節(jié)流服務。當客戶和服務器彼此交換數(shù)據(jù)前,必須先在雙方之間建立一個TCP連接,之后才能傳輸數(shù)據(jù)。TCP提供超時重發(fā),丟棄重復數(shù)據(jù),檢驗數(shù)據(jù),流量控制等功能,保證數(shù)據(jù)能從一端傳到另一端。 理想狀態(tài)下,TCP連接一旦建立,在通信雙方中的任何一方主動關閉連接前,TCP 連接都將被一直保持下去。斷開連接時服務器和客戶端均可以主動發(fā)起斷開TCP連接的請求
UDP --- 用戶數(shù)據(jù)報協(xié)議,是一個無連接的簡單的面向數(shù)據(jù)報的運輸層協(xié)議。UDP不提供可靠性,它只是把應用程序傳給IP層的數(shù)據(jù)報發(fā)送出去,但是并不能保證它們能到達目的地。由于UDP在傳輸數(shù)據(jù)報前不用在客戶和服務器之間建立一個連接,且沒有超時重發(fā)等機制,故而傳輸速度很快
【適用情況】
TCP發(fā)送的包有序號,對方收到包后要給一個反饋,如果超過一定時間還沒收到反饋就自動執(zhí)行超時重發(fā),因此TCP最大的優(yōu)點是可靠。一般網(wǎng)頁(http)、郵件(SMTP)、遠程連接(Telnet)、文件(FTP)傳送就用TCP
UDP是面向消息的協(xié)議,通信時不需要建立連接,數(shù)據(jù)的傳輸自然是不可靠的,UDP一般用于多點通信和實時的數(shù)據(jù)業(yè)務,比如語音廣播、視頻、QQ、TFTP(簡單文件傳送)、SNMP(簡單網(wǎng)絡管理協(xié)議)、RTP(實時傳送協(xié)議)RIP(路由信息協(xié)議,如報告股票市場,航空信息)、DNS(域名解釋)。注重速度流暢。
【TCP連接的三次握手】
要了解TCP,一定要知道"三次握手,四次拜拜"所謂的三次握手,就是發(fā)送數(shù)據(jù)前必須建立的連接叫三次握手,握手完了才開始發(fā)的,這也就是面向連接的意思。
第一次握手:客戶端發(fā)送syn包(syn=j)到服務器,并進入SYN_SEND狀態(tài),等待服務器確認;
第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發(fā)送一個SYN包(syn=k), ? ? ? ? ? ? ? ?即SYN+ACK包,此時服務器進入SYN_RECV狀態(tài);
第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發(fā)送確認包ACK(ack=k+1),此包發(fā)送完畢,客戶端 ? ? ? ? ? ? ? ?和服務器進入ESTABLISHED狀態(tài),完成三次握手。
(四)FTP
文件傳輸協(xié)議(File Transfer Protocol, FTP)是TCP/IP網(wǎng)絡上兩臺計算機傳送文件的協(xié)議,F(xiàn)TP是在TCP/IP網(wǎng)絡和INTERNET上最早使用的協(xié)議之一,它屬于網(wǎng)絡協(xié)議組的應用層。FTP客戶機可以給服務器發(fā)出命令來下載文件,上載文件,創(chuàng)建或改變服務器上的目錄。
1. HTTP協(xié)議與TCP/IP協(xié)議的關系
HTTP的長連接和短連接本質上是TCP長連接和短連接。HTTP屬于應用層協(xié)議,在傳輸層使用TCP協(xié)議,在網(wǎng)絡層使用IP協(xié)議。IP協(xié)議主要解決網(wǎng)絡路由和尋址問題,TCP協(xié)議主要解決如何在IP層之上可靠的傳遞數(shù)據(jù)包,使在網(wǎng)絡上的另一端收到發(fā)端發(fā)出的所有包,并且順序與發(fā)出順序一致。TCP有可靠,面向連接的特點。
2. 如何理解HTTP協(xié)議是無狀態(tài)的
HTTP協(xié)議是無狀態(tài)的,指的是協(xié)議對于事務處理沒有記憶能力,服務器不知道客戶端是什么狀態(tài)。也就是說,打開一個服務器上的網(wǎng)頁和你之前打開這個服務器上的網(wǎng)頁之間沒有任何聯(lián)系。HTTP是一個無狀態(tài)的面向連接的協(xié)議,無狀態(tài)不代表HTTP不能保持TCP連接,更不能代表HTTP使用的是UDP協(xié)議(無連接)。
3. 什么是長連接、短連接?
在HTTP/1.0中,默認使用的是短連接。也就是說,瀏覽器和服務器每進行一次HTTP操作,就建立一次連接,但任務結束就中斷連接。如果客戶端瀏覽器訪問的某個HTML或其他類型的 Web頁中包含有其他的Web資源,如JavaScript文件、圖像文件、CSS文件等;當瀏覽器每遇到這樣一個Web資源,就會建立一個HTTP會話。
但從HTTP/1.1起,默認使用長連接,用以保持連接特性。使用長連接的HTTP協(xié)議,會在響應頭有加入這行代碼:
Connection:keep-alive
在使用長連接的情況下,當一個網(wǎng)頁打開完成后,客戶端和服務器之間用于傳輸HTTP數(shù)據(jù)的 TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網(wǎng)頁,會繼續(xù)使用這一條已經(jīng)建立的連接。Keep-Alive不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如Apache)中設定這個時間。實現(xiàn)長連接要客戶端和服務端都支持長連接。
HTTP協(xié)議的長連接和短連接,實質上是TCP協(xié)議的長連接和短連接。
3.1 TCP連接
當網(wǎng)絡通信時采用TCP協(xié)議時,在真正的讀寫操作之前,server與client之間必須建立一個連接,當讀寫操作完成后,雙方不再需要這個連接 時它們可以釋放這個連接,連接的建立是需要三次握手的,而釋放則需要4次握手,所以說每個連接的建立都是需要資源消耗和時間消耗的
經(jīng)典的三次握手示意圖:

經(jīng)典的四次握手關閉圖:

3.2 TCP短連接
我們模擬一下TCP短連接的情況,client向server發(fā)起連接請求,server接到請求,然后雙方建立連接。client向server 發(fā)送消息,server回應client,然后一次讀寫就完成了,這時候雙方任何一個都可以發(fā)起close操作,不過一般都是client先發(fā)起 close操作。為什么呢,一般的server不會回復完client后立即關閉連接的,當然不排除有特殊的情況。從上面的描述看,短連接一般只會在 client/server間傳遞一次讀寫操作
短連接的優(yōu)點是:管理起來比較簡單,存在的連接都是有用的連接,不需要額外的控制手段
3.3 TCP長連接
接下來我們再模擬一下長連接的情況,client向server發(fā)起連接,server接受client連接,雙方建立連接。Client與server完成一次讀寫之后,它們之間的連接并不會主動關閉,后續(xù)的讀寫操作會繼續(xù)使用這個連接。
首先說一下TCP/IP詳解上講到的TCP?;罟δ埽;罟δ苤饕獮榉掌鲬锰峁掌鲬孟M揽蛻糁鳈C是否崩潰,從而可以代表客戶使用資源。如果客戶已經(jīng)消失,使得服務器上保留一個半開放的連接,而服務器又在等待來自客戶端的數(shù)據(jù),則服務器將應遠等待客戶端的數(shù)據(jù),保活功能就是試圖在服務 器端檢測到這種半開放的連接。
如果一個給定的連接在兩小時內沒有任何的動作,則服務器就向客戶發(fā)一個探測報文段,客戶主機必須處于以下4個狀態(tài)之一:
客戶主機依然正常運行,并從服務器可達。客戶的TCP響應正常,而服務器也知道對方是正常的,服務器在兩小時后將?;疃〞r器復位。
客戶主機已經(jīng)崩潰,并且關閉或者正在重新啟動。在任何一種情況下,客戶的TCP都沒有響應。服務端將不能收到對探測的響應,并在75秒后超時。服務器總共發(fā)送10個這樣的探測 ,每個間隔75秒。如果服務器沒有收到一個響應,它就認為客戶主機已經(jīng)關閉并終止連接。
客戶主機崩潰并已經(jīng)重新啟動。服務器將收到一個對其保活探測的響應,這個響應是一個復位,使得服務器終止這個連接。
客戶機正常運行,但是服務器不可達,這種情況與2類似,TCP能發(fā)現(xiàn)的就是沒有收到探查的響應。
3.4長連接短連接操作過程
短連接的操作步驟是:
建立連接——數(shù)據(jù)傳輸——關閉連接...建立連接——數(shù)據(jù)傳輸——關閉連接
長連接的操作步驟是:
建立連接——數(shù)據(jù)傳輸...(保持連接)...數(shù)據(jù)傳輸——關閉連接
4. 長連接和短連接的優(yōu)點和缺點
由上可以看出,長連接可以省去較多的TCP建立和關閉的操作,減少浪費,節(jié)約時間。對于頻繁請求資源的客戶來說,較適用長連接。不過這里存在一個問題,存活功能的探測周期太長,還有就是它只是探測TCP連接的存活,屬于比較斯文的做法,遇到惡意的連接時,?;罟δ芫筒粔蚴沽?。在長連接的應用場景下,client端一般不會主動關閉它們之間的連接,Client與server之間的連接如果一直不關閉的話,會存在一個問題,隨著客戶端連接越來越多,server早晚有扛不住的時候,這時候server端需要采取一些策略,如關閉一些長時間沒有讀寫事件發(fā)生的連接,這樣可 以避免一些惡意連接導致server端服務受損;如果條件再允許就可以以客戶端機器為顆粒度,限制每個客戶端的最大長連接數(shù),這樣可以完全避免某個蛋疼的客戶端連累后端服務。
短連接對于服務器來說管理較為簡單,存在的連接都是有用的連接,不需要額外的控制手段。但如果客戶請求頻繁,將在TCP的建立和關閉操作上浪費時間和帶寬。
長連接和短連接的產(chǎn)生在于client和server采取的關閉策略,具體的應用場景采用具體的策略,沒有十全十美的選擇,只有合適的選擇。
5. 什么時候用長連接,短連接?
長連接多用于操作頻繁,點對點的通訊,而且連接數(shù)不能太多情況,。每個TCP連接都需要三步握手,這需要時間,如果每個操作都是先連接,再操作的話那么處理速度會降低很多,所以每個操作完后都不斷開,次處理時直接發(fā)送數(shù)據(jù)包就OK了,不用建立TCP連接。例如:數(shù)據(jù)庫的連接用長連接, 如果用短連接頻繁的通信會造成socket錯誤,而且頻繁的socket 創(chuàng)建也是對資源的浪費。
而像WEB網(wǎng)站的http服務一般都用短鏈接,因為長連接對于服務端來說會耗費一定的資源,而像WEB網(wǎng)站這么頻繁的成千上萬甚至上億客戶端的連接用短連接會更省一些資源,如果用長連接,而且同時有成千上萬的用戶,如果每個用戶都占用一個連接的話,那可想而知吧。所以并發(fā)量大,但每個用戶無需頻繁操作情況下需用短連好。
QQ既有UDP也有TCP!
不管UDP還是TCP,最終登陸成功之后,QQ都會有一個TCP連接來保持在線狀態(tài)。這個TCP連接的遠程端口一般是80,采用UDP方式登陸的時候,端口是8000。
UDP協(xié)議是無連接方式的協(xié)議,它的效率高,速度快,占資源少,但是其傳輸機制為不可靠傳送,必須依靠輔助的算法來完成傳輸控制。QQ采用的通信協(xié)議以UDP為主,輔以TCP協(xié)議。由于QQ的服務器設計容量是海量級的應用,一臺服務器要同時容納十幾萬的并發(fā)連接,因此服務器端只有采用UDP協(xié)議與客戶端進行通訊才能保證這種超大規(guī)模的服務。
QQ客戶端之間的消息傳送也采用了UDP模式,因為國內的網(wǎng)絡環(huán)境非常復雜,而且很多用戶采用的方式是通過代理服務器共享一條線路上網(wǎng)的方式,在這些復雜的情況下,客戶端之間能彼此建立起來TCP連接的概率較小,嚴重影響傳送信息的效率。而UDP包能夠穿透大部分的代理服務器,因此QQ選擇了UDP作為客戶之間的主要通信協(xié)議。
采用UDP協(xié)議,通過服務器中轉方式。因此,現(xiàn)在的IP偵探在你僅僅跟對方發(fā)送聊天消息的時候是無法獲取到IP的。大家都知道,UDP 協(xié)議是不可靠協(xié)議,它只管發(fā)送,不管對方是否收到的,但它的傳輸很高效。但是,作為聊天軟件,怎么可以采用這樣的不可靠方式來傳輸消息呢?于是,騰訊采用了上層協(xié)議來保證可靠傳輸:如果客戶端使用UDP協(xié)議發(fā)出消息后,服務器收到該包,需要使用UDP協(xié)議發(fā)回一個應答包。如此來保證消息可以無遺漏傳輸。之所以會發(fā)生在客戶端明明看到“消息發(fā)送失敗”但對方又收到了這個消息的情況,就是因為客戶端發(fā)出的消息服務器已經(jīng)收到并轉發(fā)成功,但客戶端由于網(wǎng)絡原因沒有收到服務器的應答包引起的。