电竞比分网-中国电竞赛事及体育赛事平台

分享

傳輸模型和套接字

 piyanat 2022-08-09 發(fā)布于泰國

傳輸模型:

1、傳輸模型

基本模型:

2、TCP協(xié)議

OSI七層模型


先有模型,再有協(xié)議

TCP/IP四層模型:先有協(xié)議和應(yīng)用,再有模型
TCP:傳輸控制協(xié)議,先和目標(biāo)建立連接,再傳輸數(shù)據(jù) 相當(dāng)于打電話
UDP:用戶數(shù)據(jù)報協(xié)議,直接傳輸數(shù)據(jù),目標(biāo)地址在報文里面

TCP建立連接:三次握手


怎么連接的?為什么要三次?
客戶端:我要連接你
服務(wù)端:好的,我準(zhǔn)備好了
客戶端:我建立連接了
三次保證同步,例如因?yàn)榫W(wǎng)絡(luò)延遲導(dǎo)致兩邊收到消息延后,發(fā)出的報文就可能收不到或者不知道是誰的。

數(shù)據(jù)傳輸

斷開連接:四次揮手

客戶端:我要關(guān)閉連接了
服務(wù)端:好的,等一下
服務(wù)端:我的數(shù)據(jù)都給你了,我要斷開了
客戶端:好的,我斷開了

為什么多了一次:
因?yàn)榉?wù)端可能還數(shù)據(jù)要發(fā)

到底是一次連接傳一次數(shù)據(jù)
還是一次連接傳多次數(shù)據(jù)
都可以
HTTP協(xié)議 前著 請求一次,響應(yīng)一次
Websocket 后者 服務(wù)端有新的消息就會發(fā)給建立連接的客戶端

3、IP地址和端口

不同主機(jī)之間通信,先用ip確定某個主機(jī),再用端口確定某一個應(yīng)用程序。

除了一些服務(wù)占用的端口外,其他端口由操作系統(tǒng)分配,總共65535端口
127.0.0.1 自己的主機(jī)地址
0.0.0.0 任意的主機(jī)地址

套接字:

1.創(chuàng)建套接字實(shí)例

復(fù)制代碼
import socket
sock = socket.socket()
print(sock)

<socket.socket fd=724, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>
復(fù)制代碼


fd:正整型數(shù)據(jù),文件描述符(唯一標(biāo)識了一個socket)

domain:(域)
AF_INET     ipv4

AF_INET6    ipv6

type:(套接字類型):
SOCK_RAW     原始套接字    ——>使用原始套接字時候調(diào)用,原始套接字也就是鏈路層協(xié)議

SOCK_STREAM   字節(jié)流套接字   ——>提供順序,可靠,雙向,基于連接的字節(jié)流。 可以支持帶外數(shù)據(jù)傳輸機(jī)制。例如:TCP協(xié)議、FTP協(xié)議

SOCK_DGRAM 數(shù)據(jù)報套接字   ——>支持?jǐn)?shù)據(jù)報(無連接,不可靠的固定最大長度的消息)例如:UDP協(xié)議

SOCK_SEQPACKET 有序分組套接字 ——>為固定最大長度的數(shù)據(jù)報提供有序,可靠,雙向連接的數(shù)據(jù)傳輸路徑; 消費(fèi)者需要利用每個輸入系統(tǒng)調(diào)用讀取整個分組

protocol(協(xié)議):

IPPROTO_IP     IP傳輸協(xié)議

IPPROTO_TCP    TCP傳輸協(xié)議

IPPROTO_UDP   UDP協(xié)議

IPPROTO_SCTP   SCTP傳輸協(xié)議

IPPROTO_ICMP ICMP協(xié)議

IPPROTO_IGMP   IGMP協(xié)議

一般情況下IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP協(xié)議用的最多,UDP協(xié)議protocol就取IPPROTO_UDP,TCP協(xié)議protocol就取IPPROTO_TCP;一般情況下,我們讓protocol等于0就可以,系統(tǒng)會給它默認(rèn)的協(xié)議。但是要是使用raw socket協(xié)議,protocol就不能簡單設(shè)為0,要與type參數(shù)匹配.

三種套接字
服務(wù)端套接字:
1、監(jiān)聽套接字(相當(dāng)于前臺,把你分配給連接套接字之后,繼續(xù)監(jiān)聽。如果一次連接過多,處理不過來的會掛起)
2、連接套接字(相當(dāng)于和你交流的人)
客戶端套接字

2.建立連接

服務(wù)端的端口不能由操作系統(tǒng)分配(一般是固定的,讓客戶端知道要請求哪個端口)
服務(wù)端套接字的綁定和監(jiān)聽

復(fù)制代碼
sock.bind(('',8888)) #服務(wù)端套接字綁定自己的IP地址與端口號,客戶端那邊可以不寫,內(nèi)核會給它分配一個臨時的端口.不寫就是綁定到本地,后面8888是端口
sock
<socket.socket fd=724, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 9999)>
sock.listen(5) #開始監(jiān)聽,5表示最大掛起數(shù)
復(fù)制代碼

客戶端套接字

復(fù)制代碼
client = socket.socket()
client.connect(('127.0.0.1',9999))
client
<socket.socket fd=872, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 58311), raddr=('127.0.0.1', 9999)>
復(fù)制代碼

laddr表示本地地址,raddr表示遠(yuǎn)程連接的地址
對于客戶端來說 laddr是客戶端ip 操作系統(tǒng)分配的任意端口,raddr是服務(wù)端的ip 綁定的端口
對于服務(wù)端來說 laddr是服務(wù)端的IP 綁定的端口,raddr是客戶端的IP 客戶端系統(tǒng)分配的端口

復(fù)制代碼
t = sock.accept() # 實(shí)例一個對等連接套接字,用來和客戶端通信。如果沒有客戶端連接,會處于阻塞狀態(tài)
t
(<socket.socket fd=676, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 58311)>,
('127.0.0.1', 58311))

conn, addr = t # conn現(xiàn)在是連接套接字,addr是客戶端地址和端口
復(fù)制代碼

3.發(fā)送接受消息

復(fù)制代碼
client.send(b'hello') # 客戶端發(fā)送消息(字節(jié)類型,如果是字符串記得要encode),返回數(shù)據(jù)長度.客戶端斷開連接之后,會發(fā)送一個b''空字節(jié)
conn.recv(1024) # 連接套接字接收消息,1024表示每次最大接收數(shù)據(jù)大小,可以通過循環(huán)把所有數(shù)據(jù)接受完,接收的消息是字節(jié)類型,記得decode。如果沒有數(shù)據(jù)發(fā)過來,會處于阻塞狀態(tài)
復(fù)制代碼

4.斷開連接

client.close() #客戶端程序運(yùn)行完會自己斷開
conn.close() #服務(wù)端可以根據(jù)是否接到空,判斷是否需要斷開

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多