python web开发 网络编程 TCP/IP UDP协议
生活随笔
收集整理的這篇文章主要介紹了
python web开发 网络编程 TCP/IP UDP协议
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1. TCP/IP協議
- 1.1 IP協議
- 1.2 TCP協議
- 2. UDP協議
- 3. Socket
- 4. TCP編程
- 4.1 創建TCP服務器
- 4.2 創建TCP客戶端
- 4.3 簡易聊天工具
- 5. UDP編程
- 5.1 創建UDP服務器
- 5.2 創建UDP客戶端
learning from 《python web開發從入門到精通》
1. TCP/IP協議
大家都用同樣的協議 protocol(溝通語言)才能對話
TCP/IP協議:
- 應用層:FTP文件傳輸,Telnet遠程登錄,DNS域名系統,SMTP電子郵件傳輸…(為用戶提供服務)
- 傳輸層:TCP傳輸控制,UDP用戶數據報(端到端通信,保證順序傳輸數據和完整性)
- 網絡層:IP網際協議,IGMP互聯網組管理,ICMP互聯網控制報文(主機到主機通信)
- 鏈路層:(監視數據在主機和網絡之間的交換)
1.1 IP協議
- 數據被分成小包裹通過 IP包發出,不保證到達,不保證順序
1.2 TCP協議
- 建立在 IP 協議之上,3次握手,建立可靠連接,保證數據順序到達
- 丟失,自動重發
- TCP 報文 包含數據,源IP,目標IP,源端口,目標端口
2. UDP協議
- 面向無連接的協議,不需建立連接,只需知道對方 IP 和端口
- 不保證一定到達,但是速度比 TCP 快
3. Socket
- 兩個程序要網絡通信,都需要使用 Socket 套接字(孔,插座的意思)
- 用于描述 IP 地址 和 端口
- 服務打開一個 Socket,并綁定到一個端口上,不同的端口對應不同的服務
python中的套接字:
s = socket.socket(AddressFamily, Type)- AddressFamily,填socket.AF_INET (用于 Internet 進程間通信),填socket.AF_UNIX(用于同一臺機器進程間通信)
- Type 套接字類型,socket.SOCK_STREAM 流式套接字(主要用于 TCP),socket.SOCK_DGRAM 數據包套接字(主要用于 UDP)
常用函數:https://www.runoob.com/python/python-socket.html
| 服務器端套接字 | |
| s.bind() | 綁定地址(host,port)到套接字, 在 AF_INET下,以元組(host,port)的形式表示地址。 |
| s.listen() | 開始 TCP 監聽。backlog 指定在拒絕連接之前,操作系統可以掛起的最大連接數量。該值至少為 1,大部分應用程序設為 5 就可以了。 |
| s.accept() | 被動接受TCP客戶端連接,(阻塞式)等待連接的到來 |
| 客戶端套接字 | |
| s.connect() | 主動初始化TCP服務器連接,。一般address的格式為元組(hostname,port),如果連接出錯,返回socket.error錯誤。 |
| s.connect_ex() | connect()函數的擴展版本,出錯時返回出錯碼,而不是拋出異常 |
| 公共用途的套接字函數 | |
| s.recv() | 接收 TCP 數據,數據以字符串形式返回,bufsize 指定要接收的最大數據量。flag 提供有關消息的其他信息,通常可以忽略。 |
| s.send() | 發送 TCP 數據,將 string 中的數據發送到連接的套接字。返回值是要發送的字節數量,該數量可能小于 string 的字節大小。 |
| s.sendall() | 完整發送 TCP 數據。將 string 中的數據發送到連接的套接字,但在返回之前會嘗試發送所有數據。成功返回 None,失敗則拋出異常。 |
| s.recvfrom() | 接收 UDP 數據,與 recv() 類似,但返回值是(data,address)。其中 data 是包含接收數據的字符串,address 是發送數據的套接字地址。 |
| s.sendto() | 發送 UDP 數據,將數據發送到套接字,address 是形式為(ipaddr,port)的元組,指定遠程地址。返回值是發送的字節數。 |
| s.close() | 關閉套接字 |
| s.getpeername() | 返回連接套接字的遠程地址。返回值通常是元組(ipaddr,port)。 |
| s.getsockname() | 返回套接字自己的地址。通常是一個元組(ipaddr,port) |
| s.setsockopt(level,optname,value) | 設置給定套接字選項的值。 |
| s.getsockopt(level,optname[.buflen]) | 返回套接字選項的值。 |
| s.settimeout(timeout) | 設置套接字操作的超時期,timeout是一個浮點數,單位是秒。值為None表示沒有超時期。一般,超時期應該在剛創建套接字時設置,因為它們可能用于連接的操作(如connect()) |
| s.gettimeout() | 返回當前超時期的值,單位是秒,如果沒有設置超時期,則返回None。 |
| s.fileno() | 返回套接字的文件描述符。 |
| s.setblocking(flag) | 如果flag為0,則將套接字設為非阻塞模式,否則將套接字設為阻塞模式(默認值)。非阻塞模式下,如果調用recv()沒有發現任何數據,或send()調用無法立即發送數據,那么將引起socket.error異常。 |
| s.makefile() | 創建一個與該套接字相關連的文件 |
4. TCP編程
主動發起連接的是:客戶端
被動響應連接的是:服務器
4.1 創建TCP服務器
例子:使用 socket 模塊,通過客戶端瀏覽器 向 本地服務器(127.0.0.1) 發起請求;服務器接到請求,向瀏覽器發送 hello world
import sockethost = "127.0.0.1" # IP port = 8080 # 端口 web = socket.socket(socket.AF_INET, socket.SOCK_STREAM) web.bind((host, port)) # 綁定端口 web.listen(5) # 監聽,最多5個連接 print("服務器啟動成功, 等待客戶端連接...") while True:conn, addr = web.accept() # 建立客戶端連接print("客戶端連接成功, 地址:", addr)data = conn.recv(1024) # 獲取客戶端發送的數據print("接收到客戶端發送的數據:", data.decode())conn.sendall(b'HTTP/1.1 200 OK\r\n\r\nHello World, Michael!') # 發送數據給客戶端conn.close() # 關閉連接print("客戶端連接關閉") 服務器啟動成功, 等待客戶端連接... 客戶端連接成功, 地址: ('127.0.0.1', 7631) 接收到客戶端發送的數據: GET / HTTP/1.1 Host: 127.0.0.1:8080 Connection: keep-alive sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Microsoft Edge";v="96" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.34 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Sec-Fetch-Site: none Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6客戶端連接關閉 客戶端連接成功, 地址: ('127.0.0.1', 7632) 接收到客戶端發送的數據: GET /favicon.ico HTTP/1.1 Host: 127.0.0.1:8080 Connection: keep-alive sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Microsoft Edge";v="96" sec-ch-ua-mobile: ?0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.34 sec-ch-ua-platform: "Windows" Accept: image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: no-cors Sec-Fetch-Dest: image Referer: http://127.0.0.1:8080/ Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6客戶端連接關閉4.2 創建TCP客戶端
客戶端比較簡單一點
import sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = "127.0.0.1" port = 8080 s.connect((host, port)) while True:send_data = input("請輸入要發送的數據:")if send_data == "exit":breaks.send(send_data.encode("utf-8"))recvData = s.recv(1024).decode("utf-8") # 最大接收1024字節print("接收到的數據:", recvData) s.close()4.3 簡易聊天工具
服務端
import sockethost = socket.gethostname() port = 12345 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((host, port)) s.listen(1) sock, addr = s.accept() print('建立連接:', addr) info = sock.recv(1024).decode() while info != "byebye":if info:print("收到信息:", info)send_data = input("請輸入發送的信息:")sock.send(send_data.encode())if send_data == "byebye":breakinfo = sock.recv(1024).decode() sock.close() s.close()客戶端
import sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = socket.gethostname() port = 12345 s.connect((host, port)) print("已經連接到服務器") info = '' while info != 'byebye':send_data = input("請輸入要發送的數據:")s.send(send_data.encode())if send_data == 'byebye':breakinfo = s.recv(1024).decode()print("收到服務器的數據:", info) s.close()5. UDP編程
UDP 面向消息的協議,無需建立連接,傳輸是不可靠的,一般用于:
- 語音廣播,視頻,聊天軟件,TFTP(簡單文件傳送),SNMP(簡單網絡管理協議),RIP(路由信息協議),DNS(域名解釋)
5.1 創建UDP服務器
例子:在客戶端輸入攝氏溫度,發送給服務器,轉換為華氏溫度,發送給客戶端顯示
import sockets = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP套接字 s.bind(('127.0.0.1', 1314)) print('綁定 UDP服務 到 1314 端口') data, addr = s.recvfrom(1024) # 收到的數據是 byte 類型 data = float(data) * 1.8 + 32 send_data = "轉換后的溫度(華氏溫度):" + str(data) print("從%s:%s收到請求數據" % addr) s.sendto(send_data.encode('utf-8'), addr) # 發送數據給客戶端 s.close()5.2 創建UDP客戶端
import sockets = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) data = input("請輸入要轉換的攝氏溫度:") s.sendto(data.encode(), ("127.0.0.1", 1314)) print(s.recv(1024).decode()) s.close()總結
以上是生活随笔為你收集整理的python web开发 网络编程 TCP/IP UDP协议的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: fastapi 响应模型 / 响应状态码
- 下一篇: websocket python爬虫_p