Sokect 自定義傳輸

什么是Socket

網(wǎng)絡(luò)上的兩個(gè)程序通過(guò)一個(gè)雙向的通信連接實(shí)現(xiàn)數(shù)據(jù)的交換,這個(gè)連接的一端稱為一個(gè)socket。

實(shí)際上socket是對(duì)TCP/IP協(xié)議的封裝,Socket本身并不是協(xié)議,而是一個(gè)調(diào)用接口(API)。

俗稱套接字

他介與應(yīng)用層和傳輸層之間

IP協(xié)議對(duì)應(yīng)于網(wǎng)絡(luò)層,TCP協(xié)議對(duì)應(yīng)于傳輸層,而HTTP協(xié)議對(duì)應(yīng)于應(yīng)用層。

TPC/IP協(xié)議是傳輸層協(xié)議,主要解決數(shù)據(jù)如何在網(wǎng)絡(luò)中傳輸,而HTTP是應(yīng)用層協(xié)議,主要解決如何包裝數(shù)據(jù)。

Socket自定義傳輸

 建立Socket連接至少需要一對(duì)套接字,其中一個(gè)運(yùn)行于客戶端,稱為ClientSocket ,另一個(gè)運(yùn)行于服務(wù)器端,稱為ServerSocket 。

套接字之間的連接過(guò)程分為三個(gè)步驟:服務(wù)器監(jiān)聽(tīng),客戶端請(qǐng)求,連接確認(rèn)。

下面是流程圖

一.開(kāi)啟服務(wù)器ServerSocket

對(duì)于我們的Mac來(lái)說(shuō)開(kāi)啟nc netcat 打卡命令行輸入nc -lk? 端口號(hào)

socket() -->bind() -- >listen()-- accpet() -- 客戶端和服務(wù)器開(kāi)始讀寫(xiě)操作 -- 收到客戶端關(guān)閉連接請(qǐng)求消息--->關(guān)閉連接

bind()函數(shù)通過(guò)給一個(gè)未命名套接口分配一個(gè)本地名字來(lái)為套接口建立本地捆綁(主機(jī)地址/端口號(hào)

struct sockaddr_in 通過(guò)這個(gè)結(jié)構(gòu)里面內(nèi)容捆綁接口下面會(huì)描述這個(gè)接口

listen() 創(chuàng)建一個(gè)套接口并監(jiān)聽(tīng)申請(qǐng)的連接

我這篇文章主要實(shí)現(xiàn)客戶端的請(qǐng)求實(shí)現(xiàn)

二.客戶端連接請(qǐng)求

第一步創(chuàng)建socket

創(chuàng)建socket (導(dǎo)入對(duì)應(yīng)的頭文件<netinet/in.h>,<sys/socket.h>,<arpa/inet.h>)

socket(int, int, int)

第一個(gè)參數(shù) 協(xié)議域 AF_INET(ipv4)、AF_INET6(ipv6)....

第二次參數(shù):指定Socket類型。常見(jiàn)的2種

sock_stream是基于TCP的 是有保障的(即能保證數(shù)據(jù)正確傳送到對(duì)方)面向連接的SOCKET,多用于資料(如文件)傳送。

sock_dgram 是基于UDP的, 是無(wú)保障的面向消息的socket , 主要用于在網(wǎng)絡(luò)上發(fā)廣播信息。

第三個(gè)次參數(shù):指定協(xié)議? IPPROTO_TCP IPPROTO_UDP



第二步創(chuàng)建連接

connect(int, const struct sockaddr , socklen_t)? (經(jīng)過(guò)3次握手)

? ? ? ? 參數(shù)一:套接字描述符

? ? ? ? 參數(shù)二: struct sockaddr_in

? ? ? ? 參數(shù)三:參數(shù)二sockaddr的長(zhǎng)度,可以通過(guò)sizeof(struct sockaddr)獲得

? ? ? sockaddr 結(jié)構(gòu)體

第三步發(fā)送消息

s:一個(gè)用于標(biāo)識(shí)已連接套接口的描述字。

buf:包含待發(fā)送數(shù)據(jù)的緩沖區(qū)。

len:緩沖區(qū)中數(shù)據(jù)的長(zhǎng)度。

flags:調(diào)用執(zhí)行方式。一般填0

send(<#int#>, <#const void *#>, <#size_t#>, <#int#>)



第四部接收消息

recv(int, void *, size_t, int)

我模擬了一個(gè)聊天的效果

啟動(dòng)了一個(gè)定時(shí)器每過(guò)一段時(shí)間去取一次數(shù)據(jù).模擬聊天

值得注意的是recv 使用了堵塞的方式獲取數(shù)據(jù),所以把他放在子線程去做數(shù)據(jù)的接收

第五步關(guān)閉連接

close(int)

我將socket的創(chuàng)建,連接,發(fā)送,接收,和關(guān)閉封裝到一個(gè)類里面進(jìn)行操作

建立連接和接收服務(wù)器數(shù)據(jù)

本地回環(huán)地址建立服務(wù)器的連接,連接6969端口

發(fā)送數(shù)據(jù)

請(qǐng)求到數(shù)據(jù)的結(jié)果

模擬發(fā)送http的請(qǐng)求


通過(guò)命令行 獲取網(wǎng)址的地址


一般的端口號(hào)都是80

接收數(shù)據(jù)

接收數(shù)據(jù)的具體實(shí)現(xiàn)

使用socket 發(fā)送http網(wǎng)絡(luò)請(qǐng)求 App Transport Security Settings 可以繞過(guò)安全協(xié)議的限制,說(shuō)明我們高級(jí)NSURLSession 對(duì)是否遵守這個(gè)權(quán)限做了判斷

OSI七層模型

應(yīng)用層

? ? 網(wǎng)絡(luò)服務(wù)與最終用戶的一個(gè)接口。

? ? 協(xié)議有:HTTP FTP TFTP SMTP SNMP DNS TELNET HTTPS POP3 DHCP

表示層

數(shù)據(jù)的表示、安全、壓縮。(在五層模型里面已經(jīng)合并到了應(yīng)用層)

格式有,JPEG、ASCll、DECOIC、加密格式等

會(huì)話層

建立、管理、終止會(huì)話。(在五層模型里面已經(jīng)合并到了應(yīng)用層)

對(duì)應(yīng)主機(jī)進(jìn)程,指本地主機(jī)與遠(yuǎn)程主機(jī)正在進(jìn)行的會(huì)話

傳輸層

定義傳輸數(shù)據(jù)的協(xié)議端口號(hào),以及流控和差錯(cuò)校驗(yàn)。

協(xié)議有:TCP UDP,數(shù)據(jù)包一旦離開(kāi)網(wǎng)卡即進(jìn)入網(wǎng)絡(luò)傳輸層

網(wǎng)絡(luò)層

進(jìn)行邏輯地址尋址,實(shí)現(xiàn)不同網(wǎng)絡(luò)之間的路徑選擇。

協(xié)議有:(最主要的主要)IP(IPV4 IPV6) ICMP IGMP? ARP RARP

數(shù)據(jù)鏈路層

建立邏輯連接、進(jìn)行硬件地址尋址、差錯(cuò)校驗(yàn) 等功能。

將比特組合成字節(jié)進(jìn)而組合成幀,用MAC地址訪問(wèn)介質(zhì),錯(cuò)誤發(fā)現(xiàn)但不能糾正。

物理層

建立、維護(hù)、斷開(kāi)物理連接。(由底層網(wǎng)絡(luò)定義協(xié)議)

后言:

們開(kāi)發(fā)過(guò)程中一般都是用更加高級(jí)的api,寫(xiě)一點(diǎn)底層的是幫助我們理解客戶端和服務(wù)器的通訊過(guò)程,過(guò)年了梳理下知識(shí)點(diǎn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容