傳輸模型:1、傳輸模型基本模型:
2、TCP協(xié)議OSI七層模型
TCP/IP四層模型:先有協(xié)議和應(yīng)用,再有模型 TCP建立連接:三次握手
數(shù)據(jù)傳輸
斷開(kāi)連接:四次揮手
客戶端:我要關(guān)閉連接了 為什么多了一次: 到底是一次連接傳一次數(shù)據(jù) 3、IP地址和端口
不同主機(jī)之間通信,先用ip確定某個(gè)主機(jī),再用端口確定某一個(gè)應(yīng)用程序。 除了一些服務(wù)占用的端口外,其他端口由操作系統(tǒng)分配,總共65535端口 套接字:
1.創(chuàng)建套接字實(shí)例import socket sock = socket.socket() print(sock) <socket.socket fd=724, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>
domain:(域) AF_INET6 ipv6 type:(套接字類型): SOCK_STREAM 字節(jié)流套接字 ——>提供順序,可靠,雙向,基于連接的字節(jié)流。 可以支持帶外數(shù)據(jù)傳輸機(jī)制。例如:TCP協(xié)議、FTP協(xié)議 SOCK_DGRAM 數(shù)據(jù)報(bào)套接字 ——>支持?jǐn)?shù)據(jù)報(bào)(無(wú)連接,不可靠的固定最大長(zhǎng)度的消息)例如:UDP協(xié)議 SOCK_SEQPACKET 有序分組套接字 ——>為固定最大長(zhǎng)度的數(shù)據(jù)報(bào)提供有序,可靠,雙向連接的數(shù)據(jù)傳輸路徑; 消費(fèi)者需要利用每個(gè)輸入系統(tǒng)調(diào)用讀取整個(gè)分組 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)會(huì)給它默認(rèn)的協(xié)議。但是要是使用raw socket協(xié)議,protocol就不能簡(jiǎn)單設(shè)為0,要與type參數(shù)匹配. 三種套接字 2.建立連接服務(wù)端的端口不能由操作系統(tǒng)分配(一般是固定的,讓客戶端知道要請(qǐng)求哪個(gè)端口) sock.bind(('',8888)) #服務(wù)端套接字綁定自己的IP地址與端口號(hào),客戶端那邊可以不寫,內(nèi)核會(huì)給它分配一個(gè)臨時(shí)的端口.不寫就是綁定到本地,后面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) #開(kāi)始監(jiān)聽(tīng),5表示最大掛起數(shù)
客戶端套接字 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)> laddr表示本地地址,raddr表示遠(yuǎn)程連接的地址 t = sock.accept() # 實(shí)例一個(gè)對(duì)等連接套接字,用來(lái)和客戶端通信。如果沒(méi)有客戶端連接,會(huì)處于阻塞狀態(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是客戶端地址和端口 3.發(fā)送接受消息client.send(b'hello') # 客戶端發(fā)送消息(字節(jié)類型,如果是字符串記得要encode),返回?cái)?shù)據(jù)長(zhǎng)度.客戶端斷開(kāi)連接之后,會(huì)發(fā)送一個(gè)b''空字節(jié) conn.recv(1024) # 連接套接字接收消息,1024表示每次最大接收數(shù)據(jù)大小,可以通過(guò)循環(huán)把所有數(shù)據(jù)接受完,接收的消息是字節(jié)類型,記得decode。如果沒(méi)有數(shù)據(jù)發(fā)過(guò)來(lái),會(huì)處于阻塞狀態(tài) 4.斷開(kāi)連接client.close() #客戶端程序運(yùn)行完會(huì)自己斷開(kāi) conn.close() #服務(wù)端可以根據(jù)是否接到空,判斷是否需要斷開(kāi) |
|
|