標籤:int sea 綁定 nec break 資料連結層 res set 電信
網路通訊標準---網路通訊協定
互連網協議--osi七層協議
五層協議:應用程式層:應用程式層、展示層、會話層
傳輸層:傳輸層
網路層:網路層
資料連結層:資料連結層
物理層:物理層
物理層就是用來發送電訊號的
資料連結層跑協議,分組標準。 ethernet乙太網路協議,規定電訊號如何分組
電訊號拿來後是一堆資料,只要規定了怎麼分組才能拿到正確資料
ethernet規定
一組電訊號構成一個資料報,叫做幀
每一資料幀分成:前序head和資料data兩部分
但凡接入互連網必須要有網卡
每個網卡出廠都有自己的MAC地址 前六位廠商地址後幾位自己地址
MAC是全世界獨一無二的
以通訊角度來說,乙太網路協議有物理層和資料連結層已經可以實現通訊了
乙太網路有廣播的工作方式
廣播包只能在區域網路裡面傳,要不資料量太大會造成網路的故障
網路層---ip協議 ipv4/ipv6
ip資料包也分成head和data部分 ip頭的意思和乙太網路差不多
ip地址和ip子網路遮罩中間的運算得出一個地址,是網段地址
按位與運算 兩個同時是1才是1 二進位的ip地址和子網路遮罩進行計算
按照這個網段地址找到範圍,然後再找到這個機器
ipv4/ipv6網關是用來協助跨過子網的關口
跨子網,要用網關和網關進行通訊
用乙太網路的廣播方式將資料交給網關,但是得先獲得網關的MAC地址
但是我們知道的只有網關的IP地址
所以需要ARP協議,區域網路內,用IP位址解析成MAC地址。這樣用網關的IP地址擷取MAC地址
才能將資料交給網關
如果發送端主機發送了目標MAC地址為FF.FF.FF.FF.FF.FF那麼它就知道發送端需要擷取MAC
但是接受資料的主機不知道是不是向它要MAC地址,所以還需要發送一個IP地址,讓他知道是自己需要的
ARP協議裡面的
同一子網地址內都用乙太網路的廣播方式
IP地址和MAC地址可以確定一個機器在什麼位置
-------------------------------------------------------------------------------------------------------------------------------------------
傳輸層跑兩種協議:tcp協議和udp協議得到連接埠 確定要傳輸的是這個機器的哪個軟體
ip加連接埠確定了全世界獨一無二的軟體
軟體用機器的哪個連接埠,65536個連接埠前1024是作業系統用,後面全是自己的軟體用
應用程式層:httpp ftp mai 協議 可以自己定協議
資料前一般都要加頭 然後是資料
DHCP :自動分配IP地址
DNS:網域名稱服務 (DNS) 將網址網域名稱位址解析成IP地址
tcp協議:
建立雙向串連,用來進行資料的互動相互發送。
工作方式:c傳給s一個請求,然後s再發送一個確認和一個請求,然後c再發送一個確認
所以一共發送了三次,三向交握
為了確認是否以我發送的那個資料,你倆進行回應,所以我的資料要加一個序列
如果你發送回來的時候我的序列+1證明是用我的資料進行回應
tcp協議又稱為可靠協議,發送完包一定要等待對方確認收到了我的包進行了回應,才算髮成功
如果沒有回應過一段時間再發一次,所以是可靠協議。
可靠在發送完資料並不清空記憶體,直到對方回應確認收到後才收到
udp協議不用建立串連,被稱為不可靠協議,發送完資料就清空記憶體,不等對方的確認資訊。
tcp有中斷連線,udp沒有
誰最後確認資料收到誰先斷,四次揮手斷連結
------------------------------------------------------------------------------------------------------------------------------------
socket編程:
應用程式層與運輸層之間多了一個socket抽象層
將傳輸協議都封裝好直接用
基於應用程式層與傳輸層之間的抽象層
用基於網路的通訊端:AF——INET
伺服器端:先初始化socket(),然後與連接埠綁定bind()服務端的固定地址,對連接埠進行監聽listen()看誰來連結了
accept()阻塞直到有用戶端連結 和connect()組成一隊進行連結
import socket
socket.socket(socket.AF_INET,socket.SOCK_STREAM)
服務端:
import socket
#買手機
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 開啟了這個服務端最後要關閉
#綁定手機卡
phone.bind((‘127.0.0.1‘,8080))#127.0.0.1指的就是自己這台機器的IP地址
#開機
phone.listen(5)#5代表最大掛起的連結數
#等電話連結
conn,addr=phone.accept() 等待建立連結accept()等待建立
print(‘用戶端IP:%s,用戶端連接埠:%s‘%(addr[0],addr[1]))
data=conn.recv(1024) #最大收1024 recv()接受資料,括弧內最大接收量
print(data.decode(‘utf-8‘))
conn.send(data.upper()) send()發送資料
#6、掛電話
conn.close() 建立的連結要關閉
#7.關機
phone.close()
用戶端:
import socket
#買手機
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 一樣開啟這個連接埠
#綁定手機卡 用戶端沒必要綁定所以不用了
#開機 也不用監聽了
phone.connect((‘127.0.0.1‘,8080)) 主動建立連結,前面IP地址後面是連接埠
phone.send(‘hello‘.encode(‘utf-8‘)) 發送資料
data=phone.recv(1024)
print(data.decode(‘utf-8‘))
#關機
phone.close() 同樣要關機
持久性資料的互動,還有排隊的進行連結:
服務端:
import socket
#買手機
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#綁定手機卡
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind((‘192.168.11.52‘,8080))#127.0.0.1指的就是自己這台機器的IP地址
#開機
phone.listen(5)#5代表最大掛起的連結數
#等電話連結
print(‘starting...‘)
while True: #連結迴圈
conn,addr=phone.accept()
print(‘用戶端IP:%s,用戶端連接埠:%s‘%(addr[0],addr[1]))
while True: #通訊迴圈
try: #用到try是因為有時候會發生但無法預知的錯誤
data=conn.recv(1024) #最大收1024
if not data:break #針對linux
print(data.decode(‘utf-8‘))
conn.send(data.upper())
except ConnectionResetError:
break
#6、掛電話
conn.close() #中斷連線
#7.關機
phone.close()
用戶端:
import socket
#買手機
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#綁定手機卡 用戶端沒必要綁定所以不用了
#開機 也不用監聽了
#等電話連結
phone.connect((‘192.168.11.52‘,8080))
while True:
msg=input(‘請輸入:‘).strip()
phone.send(msg.encode(‘utf-8‘))
data=phone.recv(1024)
print(data.decode(‘utf-8‘))
#關機
phone.close()
用戶端向服務端發送空訊息的話 服務端的接收會卡住
python學習 網路編程--socket