要想理解socket首先得熟悉一下tcp/ip協議族, tcp/ip(transmission control protocol/internet protocol)即傳輸控制協議/網間協議,定義了主機如何連入網際網路及資料如何再它們之間傳輸的標準,
從字面意思來看tcp/ip是tcp和ip協議的合稱,但實際上tcp/ip協議是指網際網路整個tcp/ip協議族。不同於iso模型的七個分層,tcp/ip協議參考模型把所有的tcp/ip系列協議歸類到四個抽象層中
應用層:tftp,http,snmp,ftp,smtp,dns,telnet 等等
傳輸層:tcp,udp
網路層:ip,icmp,ospf,eigrp,igmp
資料鏈路層:slip,cslip,ppp,mtu
每一抽象層建立在低一層提供的服務上,並且為高一層提供服務,看起來大概是這樣子的
我們知道兩個程序如果需要進行通訊最基本的乙個前提能能夠唯一的標識乙個程序,在本地程序通訊中我們可以使用pid來唯一標示乙個程序,但pid只在本地唯一,網路中的兩個程序pid衝突機率很大,這時候我們需要另闢它徑了,我們知道ip層的ip位址可以唯一標示主機,而tcp層協議和埠號可以唯一標示主機的乙個程序,這樣我們可以利用ip位址+協議+埠號唯一標示網路中的乙個程序。
能夠唯一標示網路中的程序後,它們就可以利用socket進行通訊了,什麼是socket呢?我們經常把socket翻譯為套接字,socket是在應用層和傳輸層之間的乙個抽象層,它把tcp/ip層複雜的操作抽象為幾個簡單的介面**用層呼叫已實現程序在網路中通訊。
socket起源於unix,在unix一切皆檔案哲學的思想下,socket是一種"開啟—讀/寫—關閉"模式的實現,伺服器和客戶端各自維護乙個"檔案",在建立連線開啟後,可以向自己檔案寫入內容供對方讀取或者讀取對方內容,通訊結束時關閉檔案。
socket是"開啟—讀/寫—關閉"模式的實現,以使用tcp協議通訊的socket為例,其互動流程大概是這樣子的
伺服器根據位址型別(ipv4,ipv6)、socket型別、協議建立socket
伺服器為socket繫結ip位址和埠號
伺服器socket監聽埠號請求,隨時準備接收客戶端發來的連線,這時候伺服器的socket並沒有被開啟
客戶端開啟socket,根據伺服器ip位址和埠號試圖連線伺服器socket。
伺服器socket接收到客戶端socket請求,被動開啟,開始接收客戶端請求,直到客戶端返回連線資訊。這時候socket進入
阻塞狀態,所謂阻塞即accept()方法一直到客戶端返回連線資訊後才返回,開始接收下乙個客戶端諒解請求。
客戶端連線成功,向伺服器傳送連線狀態資訊。
伺服器accept方法返回,連線成功
客戶端向socket寫入資訊
伺服器讀取資訊
客戶端關閉
伺服器端關閉
在tcp/ip協議中,tcp協議通過三次握手建立乙個可靠的連線
第一次握手:客戶端嘗試連線伺服器,向伺服器傳送syn包(同步序列編號synchronize sequence numbers),syn=j,客戶端進入syn_send狀態等待伺服器確認
第二次握手:伺服器接收客戶端syn包並確認(ack=j+1),同時向客戶端傳送乙個syn包(syn=k),即syn+ack包,此時伺服器進入syn_recv狀態
第三次握手:第三次握手:客戶端收到伺服器的syn+ack包,向伺服器傳送確認包ack(ack=k+1),此包傳送完畢,客戶端和伺服器進入established狀態,完成三次握手
定睛一看,伺服器socket與客戶端socket建立連線的部分其實就是大名鼎鼎的三次握手
前面提到socket是"開啟—讀/寫—關閉"模式的實現,簡單了解一下socket提供了哪些api**用程式使用,還是以tcp協議為例,看看unix下的socket api,其它語言都很類似,這裡我就簡單解釋一下方法作用和引數,具體使用有興趣同學可以看看部落格參考中的鏈結或者上網搜尋
int socket(int domain, int type, int protocol);根據指定的位址族、資料型別和協議來分配乙個socket的描述字及其所用的資源。
domain:協議族,常用的有af_inet、af_inet6、af_local、af_route其中af_inet代表使用ipv4位址
type:socket型別,常用的socket型別有,sock_stream、sock_dgram、sock_raw、sock_packet、sock_seqpacket等
protocol:協議。常用的協議有,ipproto_tcp、ipptoto_udp、ipproto_sctp、ipproto_tipc等
int bind(int sockfd, const把乙個位址族中的特定位址賦給socketstruct sockaddr *addr, socklen_t addrlen);
sockfd:socket描述字,也就是socket引用
addr:要繫結給sockfd的協議位址
addrlen:位址的長度
通常伺服器在啟動的時候都會繫結乙個眾所周知的位址(如ip位址+埠號),用於提供服務,客戶就可以通過它來接連伺服器;而客戶端就不用指定,有系統自動分配乙個埠號和自身的ip位址組合。這就是為什麼通常伺服器端在listen之前會呼叫bind(),而客戶端就不會呼叫,而是在connect()時由系統隨機生成乙個。
int listen(int sockfd, int backlog);監聽socket
sockfd:要監聽的socket描述字
backlog:相應socket可以排隊的最大連線個數
int connect(int sockfd, const連線某個socketstruct sockaddr *addr, socklen_t addrlen);
sockfd:客戶端的socket描述字
addr:伺服器的socket位址
addrlen:socket位址的長度
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);tcp伺服器監聽到客戶端請求之後,呼叫accept()函式取接收請求
sockfd:伺服器的socket描述字
addr:客戶端的socket位址
addrlen:socket位址的長度
ssize_t read(int fd, void *buf, size_t count);讀取socket內容
fd:socket描述字
buf:緩衝區
count:緩衝區長度
ssize_t write(int fd, const向socket寫入內容,其實就是傳送內容void *buf, size_t count);
fd:socket描述字
buf:緩衝區
count:緩衝區長度
int close(int fd);socket標記為以關閉 ,使相應socket描述字的引用計數-1,當引用計數為0的時候,觸發tcp客戶端向伺服器傳送終止連線請求。
什麼是Socket?Socket協議的形象描述
socket的英文原義是 孔 或 插座 在這裡作為4bds unix的程序通訊機制,取後一種意義。socket非常類似於 插座。以乙個國家級 網為例。的通話雙方相當於相互通訊的2個程序,區號是它的網路位址 區內乙個單位的交換機相當於一台主機,主機分配給每個使用者的局內號碼相當於socket號。任何使...
docker初識 Docker 初識
一 docker 簡介 docker是乙個開源的應用容器,使用者可以將web程式和服務打包到乙個輕量級 可以移植的容器中,然後發布到任務流行的linux伺服器上,實現虛擬化。同時完全是沙箱操作,即docker內部是乙個沙箱操作,專案之間不會有任何介面,並且開銷極低。二 docker centos 安...
docker初識 初識 Docker
docker 學習 docker概述 docker安裝 docker命令映象命令 容器命令 操作命令 docker映象!容器資料卷!dockerfile docker網路原理 idea整合docker docker compose docker swarm 簡化的k8s ci cd jenkins ...