初步理解socket

2021-06-21 16:14:58 字數 3887 閱讀 4327

在學習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、smtp、dns、telnet等

傳輸層:tcp和udp

網路層:ip icmp ospf eigrp igmp

鏈路層:slip cslip ppp mtu

看圖說話:

在tcp/ip協議中兩個網際網路主機通過兩個路由器和對應的層連線。各主機上的應用通過一些資料通道相互執行讀取操作:

如何唯一標識乙個程序

利用三元組:ip位址、協議、埠號。其實這是tcp/ip協議提供的解決方式,網路層的ip位址可以唯一標識網路中的主機。傳輸層的協議+埠可以唯一標識主機中的應用程式。

在能唯一標識程序後,就可以進行socket通訊了,socket是基於unix的一種「open--write/read--close」模式的一種實現。它把tcp/ip層複雜的操作抽象為幾個簡單的介面**用層呼叫以實現程序在網路中通訊。

看圖說話:

注:socket起源於unix,在unix一切皆檔案哲學的思想下,socket是一種"開啟—讀/寫—關閉"模式的實現,伺服器和客戶端各自維護乙個"檔案",在建立連線開啟後,可以向自己檔案寫入內容供對方讀取或者讀取對方內容,通訊結束時關閉檔案。

socket是"開啟—讀/寫—關閉"模式的實現,以使用tcp協議通訊的socket為例,其互動流程大概是這樣子的

伺服器根據位址型別(ipv4,ipv6)、socket型別、協議建立socket

伺服器為socket繫結ip位址和埠號

伺服器socket監聽埠號請求,隨時準備接收客戶端發來的連線,這時候伺服器的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建立連線的部分其實就是大名鼎鼎的三次握手:

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 struct sockaddr *addr, socklen_t addrlen);
把乙個位址族中的特定位址賦給socket

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 struct sockaddr *addr, socklen_t addrlen);
連線某個socket

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 void *buf, size_t count);
向socket寫入內容,其實就是傳送內容

fd:socket描述字

buf:緩衝區

count:緩衝區長度

int close(int fd);
socket標記為以關閉 ,使相應socket描述字的引用計數-1,當引用計數為0的時候,觸發tcp客戶端向伺服器傳送終止連線請求。

Socket程式設計的初步理解

對 tcp ip udp socket 程式設計這些詞你不會很陌生吧?隨著網路技術的發展,這些詞充斥著我們的耳朵。那麼我想問 1.什麼是tcp ip udp?2.socket在 呢?3.socket是什麼呢?4.你會使用它們嗎?什麼是tcp ip udp?tcp ip transmission co...

ioctl初步理解

ioctl系統呼叫是為使用者空間建立的一種控制硬體裝置的通道。比如控制串列埠的波特率,馬達的轉速等等。是使用者空間和核心空間進行通訊的方式之一。要實現乙個ioctl,需要使用者空間和核心空間兩方面的配合。如果想要乙個硬體支援ioctl,則要在其驅動函式中加入ioctl的實現,應用程式想要通過ioct...

SVN初步理解

問題二 衝突 問題描述 為了解決超時問題,只能更新.而在更新過程中,如果幾個人修改了同一檔案的同一行 此時就會產生衝突。產生原因 版本控制器不會那麼智慧型,去決定應該使用誰的 作為最終 只能將選擇權拋給使用者,讓使用者解決。系統提供三種解決方案 p postpone,延遲處理 待會我自己處理 如果選...