首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Python 原始套接字發送 TCP 數據包:從 SOCK_RAW 到 SOCK_STREAM 的正確姿勢

     編輯:程式設計綜合問答

很多初學者嘗試用 socket.SOCK_RAW 手工構造 TCP 數據包,結果發現極其複雜:需手動填寫 IP 頭、TCP 頭、校驗和、處理分片重組、三次握手狀態機……

核心誤區

# 錯誤示範:以為這樣就是發 TCP
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
sock.sendto(packet_base, 0, (IP_PACKET_IN, 12321))

SOCK_RAW + IPPROTO_TCP 意味著你負責完整構造 IP+TCP 頭部,內核不會幫你做三次握手、序列號管理、重傳、流控。這是防火牆/掃描器開發者的工作,不是應用層發數據的正規途徑。

正確做法:使用 SOCK_STREAM

# 正確示範:內核自動處理 TCP 協議細節
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # TCP 流式套接字
sock.connect(("目標IP", 目標端口))
sock.sendall(b"你的應用層數據")  # 直接發應用層 payload
sock.close()

為什麼 SOCK_STREAM 就是「TCP 的載荷」?

  • 內核協議棧:自動完成三次握手、序列號/確認號管理、滑動窗口、重傳、擁塞控制。
  • 流式語義:sendall 發送的字節流會被內核封裝為 TCP 段(Segment),TCP 頭部的 Payload 就是你的數據。
  • 無邊界:TCP 是字節流,應用層需自行定義消息邊界(定長、分隔符、長度前綴、序列化協議)。

何時才用 SOCK_RAW?

  • 實現自定義協議(非 TCP/UDP)
  • 安全研究:造特殊標誌位包、繞過防火牆測試
  • 網絡設備開發:路由器、負載均衡器內核模塊

進階:異步/高併發

生產環境建議使用 asyncio、selectors 或 Twisted/asyncio.streams 實現非阻塞 I/O,單線程處理萬級連接。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved