TCP協(xié)議對(duì)應(yīng)于傳輸層家破,而HTTP協(xié)議對(duì)應(yīng)于應(yīng)用層。從本質(zhì)上來(lái)說(shuō)购岗,二者沒(méi)有可比性汰聋。HTTP協(xié)議是建立在TCP協(xié)議基礎(chǔ)之上的。當(dāng)瀏覽器需要從服務(wù)器獲取網(wǎng)頁(yè)數(shù)據(jù)的時(shí)候喊积,會(huì)發(fā)出一次Http
請(qǐng)求烹困。Http
會(huì)通過(guò)TCP
建立起一個(gè)到服務(wù)器的連接通道,當(dāng)本次請(qǐng)求需要的數(shù)據(jù)完畢后乾吻,Http
會(huì)立即將TCP
連接斷開(kāi)髓梅,這個(gè)過(guò)程是很短的。所以Http連接是一種短連接
绎签,是一種無(wú)狀態(tài)的連接枯饿。
所謂的無(wú)狀態(tài),是指瀏覽器每次向服務(wù)器發(fā)起請(qǐng)求的時(shí)候诡必,不是通過(guò)一個(gè)連接奢方,而是每次都建立一個(gè)新的連接。如果是一個(gè)連接的話,服務(wù)器進(jìn)程中就能保持住這個(gè)連接并且在內(nèi)存中記住一些信息狀態(tài)袱巨。而每次請(qǐng)求結(jié)束后阁谆,連接就關(guān)閉,相關(guān)的內(nèi)容就釋放了愉老,所以記不住任何狀態(tài)场绿,成為無(wú)狀態(tài)連接。
隨著時(shí)間的推移嫉入,html頁(yè)面變得復(fù)雜了焰盗,里面可能嵌入了很多圖片,這時(shí)候每次訪問(wèn)圖片都需要建立一次tcp
連接就顯得低效了咒林。因此Keep-Alive
被提出用來(lái)解決效率低的問(wèn)題熬拒。從HTTP/1.1
起,默認(rèn)都開(kāi)啟了Keep-Alive
垫竞,保持連接特性澎粟,簡(jiǎn)單地說(shuō),當(dāng)一個(gè)網(wǎng)頁(yè)打開(kāi)完成后欢瞪,客戶端和服務(wù)器之間用于傳輸HTTP數(shù)據(jù)的TCP連接不會(huì)關(guān)閉活烙,如果客戶端再次訪問(wèn)這個(gè)服務(wù)器上的網(wǎng)頁(yè),會(huì)繼續(xù)使用這一條已經(jīng)建立的連接Keep-Alive
不會(huì)永久保持連接遣鼓,它有一個(gè)保持時(shí)間啸盏,可以在不同的服務(wù)器軟件
(如Apache)中設(shè)定這個(gè)時(shí)間。雖然這里使用TCP
連接保持了一段時(shí)間骑祟,但是這個(gè)時(shí)間是有限范圍的回懦,到了時(shí)間點(diǎn)依然是會(huì)關(guān)閉的,所以我們還把其看做是每次連接完成后就會(huì)關(guān)閉次企。后來(lái)怯晕,通過(guò)Session, Cookie
等相關(guān)技術(shù),也能保持一些用戶的狀態(tài)抒巢。但是還是每次都使用一個(gè)連接贫贝,依然是無(wú)狀態(tài)連接。
以前有個(gè)概念很容忍搞不清楚蛉谜。就是為什么Http
是無(wú)狀態(tài)的短連接稚晚,而TCP是有狀態(tài)的長(zhǎng)連接?Http
不是建立在TCP
的基礎(chǔ)上嗎型诚,為什么還能是短連接客燕?現(xiàn)在明白了,Http
就是在每次請(qǐng)求完成后就把TCP
連接關(guān)了狰贯,所以是短連接也搓。而我們直接通過(guò)Socket
編程使用TCP
協(xié)議的時(shí)候赏廓,因?yàn)?code>我們自己可以通過(guò)代碼區(qū)控制什么時(shí)候打開(kāi)連接什么時(shí)候關(guān)閉連接,只要我們不通過(guò)代碼把連接關(guān)閉傍妒,這個(gè)連接就會(huì)在客戶端和服務(wù)端的進(jìn)程中一直存在幔摸,相關(guān)狀態(tài)數(shù)據(jù)會(huì)一直保存著。
實(shí)際上Socket
是對(duì)TCP/IP
協(xié)議的封裝颤练,Socket
本身并不是協(xié)議既忆,而是一個(gè)調(diào)用接口(API
)。
Socket
的出現(xiàn)只是使得程序員更方便地使用TCP/IP
協(xié)議棧而已嗦玖,是對(duì)TCP/IP
協(xié)議的抽象患雇,從而形成了我們知道的一些最基本的函數(shù)接口,比如create宇挫、listen苛吱、connect、accept器瘪、send翠储、read和write
等等。
比較形象的描述:HTTP是轎車(chē)娱局,提供了封裝或者顯示數(shù)據(jù)的具體形式;Socket是發(fā)動(dòng)機(jī)彰亥,提供了網(wǎng)絡(luò)通信的能力。對(duì)于從C#編程的角度來(lái)講衰齐,為了方便,你可以直接選擇已經(jīng)制造好的轎車(chē)Http來(lái)與服務(wù)器交互继阻。但是有時(shí)候往往因?yàn)榄h(huán)境因素或者其他的一些定制的請(qǐng)求耻涛,必須要使用TCP
協(xié)議,這時(shí)就需要使用Socket
編程瘟檩,然后自己去處理獲取的數(shù)據(jù)抹缕。就像是你用已有的發(fā)動(dòng)機(jī),自己造了一輛卡車(chē)墨辛,去從服務(wù)器交互卓研。
HTTP/1.0
和HTTP/1.1
都把TCP
作為底層的傳輸協(xié)議。HTTP
客戶首先發(fā)起建立與服務(wù)器TCP
連接睹簇。一旦建立連接奏赘,瀏覽器進(jìn)程和服務(wù)器進(jìn)程就可以通過(guò)各自的套接字
來(lái)訪問(wèn)TCP。
客戶端套接字是客戶進(jìn)程和TCP連接之間的“門(mén)”太惠,服務(wù)器端套接字是服務(wù)器進(jìn)程和同一TCP連接之間的“門(mén)”磨淌。
C#代碼連接遠(yuǎn)程數(shù)據(jù)庫(kù)用的是TCP協(xié)議。
每次new 一個(gè)connection的時(shí)候凿渊,connection.open就打開(kāi)了這個(gè)TCP連接梁只。connection.Close的時(shí)候就關(guān)閉了這個(gè)連接缚柳。FTP的底層也是TCP, 不過(guò)是長(zhǎng)連接的搪锣。
傳輸大文件比較快秋忙。 需要看具體場(chǎng)景。在服務(wù)器端构舟,如果程序是采取的長(zhǎng)連接的方式灰追,那么就能控制同時(shí)連接到這個(gè)服務(wù)器的連接個(gè)數(shù),防止同時(shí)有多個(gè)連接旁壮。但是采取短連接的方式监嗜,那么就不能控制同時(shí)連接到這個(gè)服務(wù)器上的連接的個(gè)數(shù),這也是一個(gè)優(yōu)點(diǎn)抡谐,可以同時(shí)處理大量連接請(qǐng)求裁奇。但是如果連接請(qǐng)求量太大的話,可能造成服務(wù)器停止工作麦撵。
WebService不需要連接刽肠,一秒中至少可以支持上萬(wàn)/十萬(wàn)的請(qǐng)求,每次請(qǐng)求然后釋放免胃,沒(méi)有空余的內(nèi)存消耗音五。一般不會(huì)限制同時(shí)連接的個(gè)數(shù),這是優(yōu)勢(shì)羔沙。
Message Queue需要建立連接躺涝, 支持上千的連接就很吃力了。因?yàn)槊總€(gè)連接即使沒(méi)有在請(qǐng)求數(shù)據(jù)扼雏,也會(huì)在內(nèi)存中占用一定的空間存儲(chǔ)坚嗜。會(huì)限制,比如SQL Server數(shù)據(jù)庫(kù)服務(wù)器诗充,一般最多同時(shí)連接16個(gè)苍蔬。
Http協(xié)議一定通過(guò)指定的端口,80蝴蜓,所以一般計(jì)算機(jī)上不會(huì)限制這個(gè)端口碟绑,所以Http協(xié)議能夠順利通過(guò)所有機(jī)器上的防火墻。而使用Socket編程的話茎匠,就需要自己指定特定的端口格仲,那么很可能這個(gè)端口是在某個(gè)環(huán)境中禁用的,那么就無(wú)法穿透防火墻汽抚。IIS使用的是80端口抓狭,也就是這個(gè)程序一直在監(jiān)聽(tīng)著這個(gè)端口。一旦發(fā)現(xiàn)有人要建立到這個(gè)端口的連接造烁,他就會(huì)響應(yīng)否过,然后建立連接午笛。這里說(shuō)的連接都是短連接。所以你對(duì)服務(wù)器上的網(wǎng)址的請(qǐng)求苗桂,都是通過(guò)80端口送到網(wǎng)站程序的药磺。然后通過(guò)這個(gè)端口發(fā)送的客戶端瀏覽器。