回顧TCP/IP
TCP/IP(Transmission Control Protocol/Internet Protocol)即傳輸控制協(xié)議/網(wǎng)間協(xié)議,定義了主機如何連入因特網(wǎng)及數(shù)據(jù)如何再它們之間傳輸?shù)臉藴?/p>
TCP/IP協(xié)議是指因特網(wǎng)整個TCP/IP協(xié)議族。不同于ISO模型的七個分層,TCP/IP協(xié)議參考模型把所有的TCP/IP系列協(xié)議歸類到四個抽象層中
應用層:TFTP,HTTP,SNMP,F(xiàn)TP,SMTP,DNS,Telnet 等等
傳輸層:TCP,UDP
網(wǎng)絡層:IP,ICMP,OSPF,EIGRP,IGMP
數(shù)據(jù)鏈路層:SLIP,CSLIP,PPP,MTU
每一抽象層建立在低一層提供的服務上,并且為高一層提供服務,看起來大概是這樣子的


socket
兩個進程如果需要進行通訊最基本的一個前提能能夠唯一的標示一個進程,在本地進程通訊中我們可以使用PID來唯一標示一個進程,但PID只在本地唯一,網(wǎng)絡中的兩個進程PID沖突幾率很大,這時候我們需要另辟它徑了,我們知道IP層的ip地址可以唯一標示主機,而TCP層協(xié)議和端口號可以唯一標示主機的一個進程,這樣我們可以利用ip地址+協(xié)議+端口號唯一標示網(wǎng)絡中的一個進程。
能夠唯一標示網(wǎng)絡中的進程后,它們就可以利用socket進行通信了,什么是socket呢?
網(wǎng)絡上的兩個程序通過一個雙向的通信連接實現(xiàn)數(shù)據(jù)的交換,這個連接的一端稱為一個socket,建立網(wǎng)絡通信連接至少要一對端口號(socket)。socket本質是編程接口(API),對TCP/IP的封裝,TCP/IP也要提供可供程序員做網(wǎng)絡開發(fā)所用的接口,這就是Socket編程接口
我們經(jīng)常把socket翻譯為套接字,socket是在應用層和傳輸層之間的一個抽象層,它把TCP/IP層復雜的操作抽象為幾個簡單的接口供應用層調(diào)用已實現(xiàn)進程在網(wǎng)絡中通信。在Internet上的主機一般運行了多個服務軟件,同時提供幾種服務。每種服務都打開一個Socket,并綁定到一個端口上,不同的端口對應于不同的服務。
Socket是面向客戶/服務器模型而設計的,針對客戶和服務器程序提供不同的Socket系統(tǒng)調(diào)用??蛻綦S機申請一個Socket(相當于一個想打電話的人可以在任何一臺入網(wǎng)電話上撥號呼叫),系統(tǒng)為之分配一個Socket號;服務器擁有全局公認的Socket,任何客戶都可以向它發(fā)出連接請求和信息請求(相當于一個被呼叫的電話擁有一個呼叫方知道的電話號碼)。

socket起源于UNIX,在Unix一切皆文件哲學的思想下,socket是一種"打開—讀/寫—關閉"模式的實現(xiàn),服務器和客戶端各自維護一個"文件",在建立連接打開后,可以向自己文件寫入內(nèi)容供對方讀取或者讀取對方內(nèi)容,通訊結束時關閉文件。
socket通信流程
socket是"打開—讀/寫—關閉"模式的實現(xiàn),以使用TCP協(xié)議通訊的socket為例,其交互流程大概是這樣子的

服務器根據(jù)地址類型(ipv4,ipv6)、socket類型、協(xié)議創(chuàng)建socket
服務器為socket綁定ip地址和端口號
服務器socket監(jiān)聽端口號請求,隨時準備接收客戶端發(fā)來的連接,這時候服務器的socket并沒有被打開
客戶端創(chuàng)建socket
客戶端打開socket,根據(jù)服務器ip地址和端口號試圖連接服務器socket
服務器socket接收到客戶端socket請求,被動打開,開始接收客戶端請求,直到客戶端返回連接信息。這時候socket進入阻塞狀態(tài),所謂阻塞即accept()方法一直到客戶端返回連接信息后才返回,開始接收下一個客戶端諒解請求
客戶端連接成功,向服務器發(fā)送連接狀態(tài)信息
服務器accept方法返回,連接成功
客戶端向socket寫入信息
服務器讀取信息
客戶端關閉
服務器端關閉
在TCP/IP協(xié)議中,TCP協(xié)議通過三次握手建立一個可靠的連接

第一次握手:客戶端嘗試連接服務器,向服務器發(fā)送syn包(同步序列編號Synchronize Sequence Numbers),syn=j,客戶端進入SYN_SEND狀態(tài)等待服務器確認
第二次握手:服務器接收客戶端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),完成三次握手
服務器socket與客戶端socket建立連接的部分其實就是大名鼎鼎的三次握手
