網絡的概念:主機 端口 IP 協議
- 服務器:
- localhost/127.0.0.1
- 客戶端:
- 只是在本機啟動客戶端,用127.0.0.1訪問
- 服務器:
- 0.0.0.0
- 客戶端:
- 可以在本機用127.0.0.1、192.168.0.1
- 服務器:
- 192.168.0.1
- 客戶端:
- 局域網內用192.168.0.1
socket(創建套接字) --->
bind(綁定地址) --->
listen(設置監聽)--->
accept(等待鏈接) --->
recv/send(收/發消息) --->
close ()
收發函數特性:
recv特征:
- 如果建立的另一端鏈接被斷開, 則recv立即返回空字符串
- recv是從接受緩沖區取出內容,當緩沖區為空則阻塞
- recv如果一次接受不完緩沖區的內容,下次執行會自動接受
send特征:
- 如果發送的另一端不存在則會產生Pipe Broken異常
- send是從發送緩沖區發送內容,當緩沖區為滿則堵塞
網絡的收發緩存區:
在內存中開辟區域,用於
發送和接受的緩沖
作用:
- 協調數據的收發(接受和處理)速度
- 減少和磁盤的交互
sendall(date):
功能:
tcp套接字發送消息
參數:同
send
返回值:如果
發送成功則
返回None
否則返回異常
tcp粘包:
產生原因:
1.
tcp傳輸以
字節流的方式
發送消息,
消息之間沒有邊界
2.發送比
接受的速度快
影響:
對每次發送的內容是一個獨立的意識需要單獨識別時 容易使用原文件被更改
如何處理:
1.每次發送后
追加一個結尾標志,代表本次發送完畢
2.
發送一個
數據結構
3.
每次發送有一個
時間間隔
基於udp的服務端編程:
1.創建套接字:
sockfd = socket(AF_INET,SOCK_DGRAM)
2.綁定地址:
sockfd.bind()
3.消息收發
data, addr = sockfd.
recvfrom(buffersize)
功能:接受udp消息
參數:接受消息的大小
返回值:
data 接受到的內容
addr 消息發送的地址
recvfrom每次接受一個報文,
如果沒有接受到的內容則直接丟棄
sockfd.
sendto(data, addr)
功能:udp消息發送
參數:
data 要發送的內容 bytes
addr 目標地址
返回:發送字節數
4.關閉套接字:
socket.close()
import
sys
sys.argv
作用:
獲取從命令行獲取的參數內容
Python3 demo.py 參數1, 參數2.....
sys.argv[0] 是命令本身(程序本身)
tcp流式套接字和udp數據報套接字區別:
- 1.流式套接字采用字節流的方式進行傳輸,
- 而數據報套接字使用數據報形式傳輸數據
- 2.tcp套接字會產生粘包,udp不會
- 3.tcp編程可以保證消息的完整性,udp則不一定
- 4.tcp需要listen、accept、udp不用
- 5.tcp消息的發送接收使用recv、send、sendall、
- udp使用recvfrom,sendto
socket模塊和
套接字屬性(s為套接字)
- s.type:表示套接字類型
- s.family:地址類型
套接字屬性方法
s.fileno()
功能:
獲取套接字的
文件描述符
文件描述符:
每一個IO事件 操作系統都會分配一個不同的的正整數,
該正整數即為此IO操作的文件描述符
默認開啟的描述符:
- sys.stdin 0
- sys.stdout 1
- sys.stderr 2
s.getsockname()
功能:
獲取套結字綁定
的地址
s.
getpeername()
功能:
獲取鏈接套接字
客戶端的地址
s.setsockopt(level,optname, value)
(#
設置端口可立即重用 必須在鏈接端口前設置
s.setsockopt(SOL_SOcKET, SO_REUSEADDR))
功能:設置套接字選項
參數:
level:設置
選項的類型(大類型) 常用:SOL_SOCKET
optname:
子類選項
value:
要設置的值
s.getsockopt(level
, optname)
功能:
獲取套接字選項值
參數:
level:選項的類型
udp套接字應用--->
廣播
一點發送多點接收
目標地址:廣播地址 172.18.32
.255
tcp應用---> http傳輸
http協議:
超文本傳輸協議
用途:
網站中瀏覽器
網頁的獲取,基於
網站事物
數據傳輸
編寫基於http協議的
數據傳輸
特點:
1.
應用層協議,傳輸層使用tcp服務
2.
簡單、靈活,可以使用
多種編程語言操作
3.無狀態的協議,既不用記錄用戶的輸入內容
4.
http1.1 ---> http2.0(還沒發布)
技術的成熟和穩定性
http請求(request):
請求格式:
1.請求行:說明具體的
請求類別和內容
GET /index.html /HTTP/1.1
請求類別 請求內容 協議版本
請求類別:
- GET: 獲取網絡資源
- POST: 提交一定的附加數據
- HEAD: 獲取響應頭
- PUT: 更新服務器資源
- DELETE: 刪除服務器資源
- CONNECT: 未使用
- TRACE: 用於測試
- OPTIONS: 獲取服務器性能信息
2.請求頭:對
請求的具體描述
Accept:text/html
每一個鍵值對占一行,描述了一個特定信息
3.空行
4.請求體: 具體的
參數或提交的
內容
get參數或者post提交的內容
http響應(response):
響應格式:
1.響應行:
反饋具體的
響應情況
HTTP/1.1 20 OK
版本協議 響應碼 附加信息
響應碼:
- 1xx:提示信息,表示請求已經接收
- 2xx:響應成功
- 3xx:響應需要定向(重新記載鏈接第三方鏈接)
- 4xx:客戶端錯誤
- 5xx:服務器端錯誤
常見響應碼:
200 成功
404 請求
內容不存在
401 沒有訪問
權限
500 服務器
未知錯誤
503
服務器暫時
無法執行
2.響應頭:對響應
內容的具體描述
3.空行
4.響應體:
將客戶端請求內容進行返回



這里這個圖就看了一眼 沒特意去記 憑印象畫的 可能不對 但是大體邏輯應該沒錯
我去百度搜了 什么也沒搜到 不知道是不是我的打開方式不對還是什么
只搜到了上面的兩張圖..........
總結:
tcp,udp協議的區別和編程實現上的差異:
tcp:
- tcp是一種可靠的、面向有鏈接數據傳輸服務
- tcp能夠保證數據的完整性、順序性、無重復以及無差錯
- tcp是一種以文件流的形式傳輸數據的服務 文件流之間是沒有邊界
- 的所以基友可能會產生粘包的情況 粘包是因為接受速度沒有傳輸速度快
- 導致緩存區的數據擁堵 下次取出數據時從而產生非獨立數據的鏈接 這種情況
- 叫做粘包 粘包只有傳輸多個數據時才會出現
- tcp的編程需要監聽套接字 和 等待鏈接過程 只有鏈接成功才能發送數據
- 這種情況叫做三次握手、還有斷開時的四次揮手
- 三次揮手:客戶端請求鏈接、服務器返回報文、客戶端完成鏈接
- 四次揮手:客戶端請求斷開、服務器接受請求、服務器准備完畢可以斷開、客戶端斷開
- tcp收發送消息需要使用recv、send、sendall方法
- sendall比特殊 功能和send一樣 但sendall有事務 若發送成功返回None 否則觸發異常
- 鏈接時必須先運行服務器端后運行客戶端
udp:
- udp就比較簡單了 是面向無連接的不可靠的數據傳輸服務
- udp沒有數據流 接受大小取決於接收方
- 若數據超出接收方接受范圍則丟掉所有超出范圍的內容
- udp不存在粘包的情況
- udp不需要等待鏈接 沒有揮手過程 先發就發 想收就收 自由度比較高
- udp編程時收發消息使用recvfrom、sendto方法
- udp可用於廣播可以隨時斷開或鏈接
- 客戶端和服務器端可以隨時運行
什么是http?
http 是超文本傳輸協議
一種網絡數據傳輸的協議
沒錯就是 協議
並且所有的www文件都必須遵守這個標准
http作用是什么?
可以用力來網站中瀏覽器網頁獲取,基於網站上的一些數據傳輸 例如目前我正在打的字......
編寫基於http協議的數據傳輸
http協議 請求和響應的格式以及每一部分做什么
請求部分:
請求行:請求的具體類別和內容 比如說 類別、內容、版本協議
請求頭:請求具體描述
空行:就是空行
請求體:請求具體參數或內容
響應部分:
響應行:具體響應情況 比如說 版本協議 、響應碼 、附加信息
響應頭:響應具體描述
空行
響應體:響應具體參數或內容
http協議中請求的基本類型和作用:
GET:獲取網絡資源
POST:提交一定的附加數據
HEAD:獲取響應頭 響應返回的文件信息
PUT:更新服務器資源
DELETE:刪除服務器資源
TRACE:用於測試
OPIONS:獲取服務器性能信息
CONNECT:備用
http協議響應碼的類型和表達含義:
以1開頭的表示請求已經鏈接
以2開頭的表示成功接收、提示
以3開頭的代表重新定向進一步處理 第三方
以4開頭的客戶端錯誤
以5開頭的服務器錯誤
http協議請求網頁的流程:
建立連接、發送請求、響應請求、斷開鏈接
這樣的一個過程稱為一個事物
文件傳輸示例:
服務器端
from socket import * from time import sleep s = socket() s.bind(('0.0.0.0',8888)) s.listen(5) c,addr = s.accept() print("Connect from ",addr) f = open('img.jpg','rb') #將文件名稱告知對方 c.send('img.jpg'.encode()) sleep(0.1) while True: data = f.read(1024) if not data: break c.send(data) sleep(0.1) c.send('##'.encode()) data = c.recv(1024) print(data.decode()) f.close() c.close() s.close()
客戶端
from socket import * s = socket() s.connect(('172.60.50.181',8888)) filename = s.recv(1024).decode() f = open('/home/tarena/'+filename,'wb') while True: data = s.recv(1024) if data == b'##': break f.write(data) s.send("接收完成".encode()) f.close() s.close()