當我們探討兩件事物的區別和聯絡時,我們想探討些什麼?
前段時間寫了兩篇介紹 HTTP 和 WebSocket 的文章,回覆中有人說希望瞭解下WebSocket和Socket的區別。這個問題之前也有想過,自己對此是有大概的答案,可是並不太確定,於是去搜集了些資料(其實就是各種Google),看了很多以前的文件,覺得有些故事十分有趣,整理如下,算是一個外傳。
文中圖片全來自Google圖片搜尋,如侵刪。
短答案
就像Java和JavaScript,並沒有什麼太大的關係,但又不能說完全沒關係。可以這麼說:
- 命名方面,Socket是一個深入人心的概念,WebSocket借用了這一概念;
- 使用方面,完全兩個東西。
長答案
當我們探討兩件事物的區別和聯絡時,我們想探討些什麼?
對於我來說,大多數情況是想知道兩件事物本身,而並不是想只想瞭解「區別」本身。那麼對這個問題最直接的解決方法應該是去了解Socket和WebSocket的來源和用法,那麼它們的區別和聯絡就不言自明瞭。
Socket
Socket可以有很多意思,和IT較相關的本意大致是指在端到端的一個連線中,這兩個端叫做Socket。對於IT從業者來說,它往往指的是TCP/IP網路環境中的兩個連線端,大多數的API提供者(如作業系統,JDK)往往會提供基於這種概念的介面,所以對於開發者來說也往往是在說一種程式設計概念。同時,作業系統中程式間通訊也有Socket的概念,但這個Socket就不是基於網路傳輸層的協議了。
Unix 中的 Socket
作業系統中也有使用到Socket這個概念用來進行程式間通訊,它和通常說的基於TCP/IP的Socket概念十分相似,代表了在作業系統中傳輸資料的兩方,只是它不再基於網路協議,而是作業系統本身的檔案系統。
網路中的 Socket
通常所說的Socket API,是指作業系統中(也可能不是作業系統)提供的對於傳輸層(TCP/UDP)抽象的介面。現行的Socket API大致都是遵循了BSD Socket規範(包括Windows)。這裡稱規範其實不太準確,規範其實是POSIX,但BSD Unix中對於Socket的實現被廣為使用,所以成為了實際的規範。如果你要使用HTTP來構建服務,那麼就不需要關心Socket,如果你想基於TCP/IP來構建服務,那麼Socket可能就是你會接觸到的API。
從上圖中可以看到,HTTP是基於傳輸層的TCP協議的,而Socket API也是,所以只是從使用上說,可以認為Socket和HTTP類似(但一個是成文的網際網路協議,一個是一直沿用的一種程式設計概念),是對於傳輸層協議的另一種直接使用,因為按照設計,網路對使用者的介面都應該在應用層。
Socket 名稱的由來
和很多其他Internet上的事物一樣,Socket這個名稱來自於大名鼎鼎的ARPANET(Advanced Research Projects Agency),早期ARPANET中的Socket指的是一個源或者目的地址——大致就是今天我們所說的IP地址和埠號。最早的時候一個Socket指的是一個40位的數字(RFC33中說明了此用法,但在RFC36中並沒有明確地說使用40位數字來標識一個地址),其中前32為指向的地址(socket number,大致相當於IP),後8位為傳送資料的源(link,大致相當於埠號)。對他們的叫法有很多的版本,這裡列舉的並不嚴謹。
埠號的野史
隨著ARPANET的發展,後來(RFC433,Socket Number List)socket number被明確地定義為一個40位的數字,其中後8位被用來制定某個特定的應用使用(比如1是Telnet)。這8位數有很多名字:link、socket name、AEN(another eight number,看到這個名字我也是醉了),工程師逗逼起來也是挺拼的。
後來在Internet的規範制定中,才真正的用起了port number這個詞。至於為什麼埠號是16位的,我想可能有兩個原因,一是對於當時的工程師來說,如果每個埠號來標識一個程式,65535個埠號也差不多夠用了。二可能是為了對齊吧,^_^!!。
Socket 原本的意思
在上邊提到的歷史中使用到的Socket,包括TCP文件中使用到的Socket,其實指的是網路傳輸中的一端,是一個虛擬化的概念。
WebSocket
上邊簡單敘述了Socket的意義,由於年代久遠,很多事情也搞不了那麼清楚。但WebSocket是一個很晚近的東西,可以讓我們看到它是如何成為現在我們看到的這個樣子的。
WHATWG(Web Hypertext Application Technology Working Group)
關於HTML5的故事很多人都是知道的,w3c放棄了HTML,然後有一群人(也有說是這些人供職的公司,不過官方的文件上是說的個人)創立了WHATWG組織來推動HTML語言的繼續發展,同時,他們還發展了很多關於Web的技術標準,這些標準不斷地被官方所接受。WebSocket就屬於WHATWG釋出的Web Application的一部分(即HTML5)的產物。
為什麼會有 WebSocket
大約在08年的時候,WG的工程師在討論網路環境中需要一種全雙工的連線形式,剛開始一直叫做「TCPConnection」,並討論了這種協議需要支援的功能,大致已經和我們今天看到的WebSocket差不多了。他們認為基於現有的HTTP之上的一些技術(如長輪詢、Comet)並滿足不了這種需求,有必要定義一個全新的協議。
名稱的由來
在很多的關於HTML5或者WebSocket的文件中,都能看到一個名字,Hixie(Ian Hickson),他是WHATWG組織的發言人,曾供職於Netscape、Opera、Google,看工作的公司就知道這個人的背景了。
08年6月18日,一群WHATWG的工程師在討論一些技術問題,一個工程師提到說「我們之前討論的那個東西,不要叫TCPConnection 了,還是起個別的名字吧 」,接著幾個名字被提及,DuplexConnection,TCPSocket,SocketConnection ,一個叫mcarter(Michael Carter )的工程師說他馬上要寫一篇關於Comet的文章,如果可以確定這個名稱,想在文章中引用這個名字。
Socket一直以來都被人用來表示網路中一個連線的兩端,考慮到怎麼讓工程師更容易接受,後來Hixie說了一句「我看WebSocket這個名字就很適合嘛(Hixie briefly pops back online to record that “WebSocket” would probably be a good new name for the TCPConnection object)」,大家都沒有異議,緊接著mcarter在Comet Daily中發表了文章Independence Day: HTML5 WebSocket Liberates Comet From Hacks,後來隨著各大瀏覽器對WebSocket的支援,它變成了實際的標準,IETF也沿用了這個名字。
下邊是在WHATWG文件中對WebSocket介面的定義
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
enum BinaryType { "blob", "arraybuffer" }; [Constructor(USVString url, optional (DOMString or sequence<DOMString>) protocols = []), Exposed=(Window,Worker)] interface WebSocket : EventTarget { readonly attribute USVString url; // ready state const unsigned short CONNECTING = 0; const unsigned short OPEN = 1; const unsigned short CLOSING = 2; const unsigned short CLOSED = 3; readonly attribute unsigned short readyState; readonly attribute unsigned long long bufferedAmount; // networking attribute EventHandler onopen; attribute EventHandler onerror; attribute EventHandler onclose; readonly attribute DOMString extensions; readonly attribute DOMString protocol; void close([Clamp] optional unsigned short code, optional USVString reason); // messaging attribute EventHandler onmessage; attribute BinaryType binaryType; void send(USVString data); void send(Blob data); void send(ArrayBuffer data); void send(ArrayBufferView data); }; |
內容的確定
大多數新技術的出現都是建立在已有技術的鋪墊之上的,WebSocket內容的確定也是如此,其中就有Comet看不到的貢獻,Comet是一個很有趣的技術,有興趣可以看看這裡
結論
可以把WebSocket想象成HTTP,HTTP和Socket什麼關係,WebSocket和Socket就是什麼關係。