最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python socket庫(kù)實(shí)現(xiàn)原生TCP請(qǐng)求

 更新時(shí)間:2026年06月29日 08:13:57   作者:detayun  
本文詳細(xì)介紹了如何使用Python內(nèi)置的socket庫(kù)實(shí)現(xiàn)TCP客戶端與服務(wù)端通信,涵蓋短連接與長(zhǎng)連接場(chǎng)景,并深入探討了TCP與UDP的核心區(qū)別與實(shí)戰(zhàn)應(yīng)用,感興趣的小伙伴可以了解下

一、前言

我們平時(shí)調(diào)用接口使用requests、aiohttp,底層全部都是TCP協(xié)議。HTTP只是構(gòu)建在TCP之上的應(yīng)用層協(xié)議。

很多運(yùn)維、后端場(chǎng)景需要直接操作TCP裸連接:端口連通性探測(cè)、自定義報(bào)文通信、服務(wù)心跳、Socket長(zhǎng)連接。

TCP是面向連接的可靠傳輸協(xié)議,通信分為三步:建立連接 → 收發(fā)數(shù)據(jù) → 斷開(kāi)連接。

本文使用Python內(nèi)置socket庫(kù),不依賴任何第三方庫(kù),從零實(shí)現(xiàn)TCP客戶端與服務(wù)端通信。

二、TCP與UDP核心區(qū)別

  1. TCP需要先三次握手建立連接,UDP直接發(fā)包;
  2. TCP保證數(shù)據(jù)有序、不丟失;UDP只管發(fā)送,不保障送達(dá);
  3. TCP使用SOCK_STREAM,UDP使用SOCK_DGRAM;
  4. TCP適合文件傳輸、接口調(diào)用;UDP適合廣播、實(shí)時(shí)數(shù)據(jù)流。

三、基礎(chǔ)TCP客戶端:短連接請(qǐng)求

短連接:連接建立,收發(fā)一次數(shù)據(jù),立刻關(guān)閉。

核心方法:

  • socket() 創(chuàng)建套接字
  • connect() 連接服務(wù)端IP端口
  • send() 發(fā)送字節(jié)數(shù)據(jù)
  • recv() 接收返回?cái)?shù)據(jù)
import socket

# 創(chuàng)建TCP套接字 SOCK_STREAM = TCP
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 目標(biāo)服務(wù)端地址
host = "127.0.0.1"
port = 9000

try:
    # 發(fā)起三次握手,建立TCP連接
    client.connect((host, port))
    # 發(fā)送二進(jìn)制數(shù)據(jù)
    client.send("Hello TCP Server".encode("utf-8"))
    # 阻塞等待接收服務(wù)端返回?cái)?shù)據(jù),緩沖區(qū)1024字節(jié)
    recv_data = client.recv(1024)
    print("收到服務(wù)端返回:", recv_data.decode("utf-8"))
except ConnectionRefusedError:
    print("端口未開(kāi)放,TCP連接失敗")
finally:
    # 關(guān)閉連接,釋放資源
    client.close()

四、TCP服務(wù)端:監(jiān)聽(tīng)端口并處理連接

服務(wù)端固定端口監(jiān)聽(tīng),等待客戶端接入。

關(guān)鍵函數(shù):

  • bind() 綁定IP和端口
  • listen() 開(kāi)啟監(jiān)聽(tīng)
  • accept() 阻塞等待新客戶端接入
import socket

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 綁定0.0.0.0,允許局域網(wǎng)所有設(shè)備訪問(wèn)
server.bind(("0.0.0.0", 9000))
# 開(kāi)啟監(jiān)聽(tīng),最大掛起隊(duì)列5
server.listen(5)
print("TCP服務(wù)端已啟動(dòng),監(jiān)聽(tīng)9000端口")

while True:
    # 阻塞等待客戶端連接
    conn, addr = server.accept()
    print(f"新客戶端接入:{addr}")
    # 接收客戶端消息
    data = conn.recv(1024)
    print("收到消息:", data.decode())
    # 回復(fù)數(shù)據(jù)
    conn.send("消息已收到".encode("utf-8"))
    # 關(guān)閉本次客戶端連接(短連接模式)
    conn.close()

運(yùn)行順序:先啟動(dòng)服務(wù)端,再運(yùn)行客戶端,即可完成一次TCP通信。

五、TCP長(zhǎng)連接:不斷開(kāi)持續(xù)收發(fā)數(shù)據(jù)

短連接每次通信都要重新握手,開(kāi)銷很大。長(zhǎng)連接建立一次連接,反復(fù)收發(fā)多條消息。

客戶端長(zhǎng)連接代碼

import socket

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("127.0.0.1", 9000))

# 循環(huán)發(fā)送多條數(shù)據(jù),連接不斷開(kāi)
for i in range(3):
    msg = f"第{i+1}條消息".encode("utf-8")
    client.send(msg)
    res = client.recv(1024)
    print("接收:", res.decode())

client.close()

服務(wù)端改造(持續(xù)讀取數(shù)據(jù))

import socket

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("0.0.0.0", 9000))
server.listen(5)

while True:
    conn, addr = server.accept()
    print("客戶端已連接")
    # 持續(xù)讀取客戶端消息
    while True:
        data = conn.recv(1024)
        if not data:
            # 客戶端關(guān)閉連接,recv會(huì)拿到空字節(jié)
            break
        print(data.decode())
        conn.send("ok".encode())
    conn.close()

六、實(shí)戰(zhàn)場(chǎng)景1:TCP端口存活檢測(cè)

運(yùn)維最常用場(chǎng)景:批量探測(cè)服務(wù)器端口是否開(kāi)放,本質(zhì)就是嘗試建立TCP連接。

import socket

def check_tcp_port(host, port, timeout=2):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(timeout)
    try:
        sock.connect((host, port))
        return True, "端口開(kāi)放"
    except Exception:
        return False, "端口關(guān)閉或無(wú)法連接"
    finally:
        sock.close()

# 測(cè)試
print(check_tcp_port("www.baidu.com", 80))
print(check_tcp_port("127.0.0.1", 9999))

這個(gè)端口探測(cè)比UDP探測(cè)更加可靠,廣泛用于內(nèi)網(wǎng)資產(chǎn)掃描、節(jié)點(diǎn)健康檢測(cè)。

七、實(shí)戰(zhàn)場(chǎng)景2:手動(dòng)發(fā)送原始HTTP報(bào)文(裸TCP訪問(wèn)網(wǎng)頁(yè))

HTTP協(xié)議就是文本TCP報(bào)文,我們不用requests,直接用TCP套接字訪問(wèn)網(wǎng)頁(yè):

import socket

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("www.baidu.com", 80))

# 原始HTTP GET報(bào)文
http_msg = b"GET / HTTP/1.1\r\nHost: www.baidu.com\r\nConnection: close\r\n\r\n"
client.send(http_msg)

# 接收網(wǎng)頁(yè)響應(yīng)
response = client.recv(4096)
print(response.decode("utf-8", errors="ignore"))
client.close()

運(yùn)行就能拿到百度的HTTP響應(yīng)頭與網(wǎng)頁(yè)正文,可以直觀理解HTTP是封裝在TCP之上的應(yīng)用層協(xié)議。

八、TCP開(kāi)發(fā)常見(jiàn)問(wèn)題與避坑

recv阻塞卡死:recv默認(rèn)無(wú)限等待,可以設(shè)置sock.settimeout(3)超時(shí)斷開(kāi)。

粘包問(wèn)題:TCP是流式字節(jié)流,沒(méi)有數(shù)據(jù)包邊界,多條數(shù)據(jù)會(huì)黏在一起。自定義通信協(xié)議時(shí),必須加數(shù)據(jù)長(zhǎng)度分隔符。

客戶端沒(méi)有正常close,導(dǎo)致端口被占用(TIME_WAIT):程序一定要正常關(guān)閉套接字;服務(wù)端可以開(kāi)啟端口復(fù)用:

server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

數(shù)據(jù)必須為bytes字節(jié)串:字符串一定要encode,不能直接發(fā)送str字符串。

單線程服務(wù)端只能處理一個(gè)客戶端:上面的服務(wù)端是單線程,一次只能服務(wù)一個(gè)連接,高并發(fā)場(chǎng)景需要搭配多線程/多協(xié)程處理每一條TCP連接。

九、異步TCP(asyncio高級(jí)用法)

高并發(fā)大量TCP探測(cè)時(shí),同步socket效率太低,可以使用asyncio創(chuàng)建異步TCP連接,上萬(wàn)條連接輕松調(diào)度,占用內(nèi)存極低,非常適合批量端口巡檢。

十、總結(jié)

  1. TCP核心流程:創(chuàng)建套接字 → connect建立連接 → send/recv收發(fā)數(shù)據(jù) → close斷開(kāi);
  2. 短連接一發(fā)一關(guān),長(zhǎng)連接復(fù)用TCP通道減少握手開(kāi)銷;
  3. 原生Socket TCP可以實(shí)現(xiàn)端口探測(cè)、自定義報(bào)文、裸HTTP請(qǐng)求;
  4. requests、urllib、爬蟲(chóng)框架底層全部都是對(duì)TCP Socket的封裝。

原生TCP網(wǎng)絡(luò)編程是后端、運(yùn)維、網(wǎng)絡(luò)爬蟲(chóng)的基本功,掌握裸Socket通信,才能真正理解互聯(lián)網(wǎng)數(shù)據(jù)傳輸?shù)牡讓舆壿嫛?/p>

如果你想,我可以再續(xù)寫一版:多線程TCP服務(wù)端 + 異步批量TCP端口檢測(cè)代碼。

到此這篇關(guān)于Python socket庫(kù)實(shí)現(xiàn)原生TCP請(qǐng)求的文章就介紹到這了,更多相關(guān)Python socket實(shí)現(xiàn)TCP請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Scrapy Redis入門實(shí)戰(zhàn)

    詳解Scrapy Redis入門實(shí)戰(zhàn)

    這篇文章主要介紹了詳解Scrapy Redis入門實(shí)戰(zhàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 在PyCharm中控制臺(tái)輸出日志分層級(jí)分顏色顯示的方法

    在PyCharm中控制臺(tái)輸出日志分層級(jí)分顏色顯示的方法

    今天小編就為大家分享一篇在PyCharm中控制臺(tái)輸出日志分層級(jí)分顏色顯示的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • python如何實(shí)現(xiàn)excel數(shù)據(jù)添加到mongodb

    python如何實(shí)現(xiàn)excel數(shù)據(jù)添加到mongodb

    本文介紹了python是如何實(shí)現(xiàn)excel數(shù)據(jù)添加到mongodb,為了將數(shù)據(jù)導(dǎo)入mongodb,引入了pymongo,xlrd包,需要的朋友可以參考下
    2015-07-07
  • Python?Matplotlib繪制箱線圖boxplot()函數(shù)詳解

    Python?Matplotlib繪制箱線圖boxplot()函數(shù)詳解

    箱線圖一般用來(lái)展現(xiàn)數(shù)據(jù)的分布(如上下四分位值、中位數(shù)等),同時(shí)也可以用箱線圖來(lái)反映數(shù)據(jù)的異常情況,下面這篇文章主要給大家介紹了關(guān)于Python?Matplotlib繪制箱線圖boxplot()函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • Python3簡(jiǎn)單實(shí)現(xiàn)串口通信的方法

    Python3簡(jiǎn)單實(shí)現(xiàn)串口通信的方法

    今天小編就為大家分享一篇Python3簡(jiǎn)單實(shí)現(xiàn)串口通信的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-06-06
  • 回歸預(yù)測(cè)分析python數(shù)據(jù)化運(yùn)營(yíng)線性回歸總結(jié)

    回歸預(yù)測(cè)分析python數(shù)據(jù)化運(yùn)營(yíng)線性回歸總結(jié)

    本文主要介紹了python數(shù)據(jù)化運(yùn)營(yíng)中的線性回歸一般應(yīng)用場(chǎng)景,常用方法,回歸實(shí)現(xiàn),回歸評(píng)估指標(biāo),效果可視化等,并采用了回歸預(yù)測(cè)分析的數(shù)據(jù)預(yù)測(cè)方法
    2021-08-08
  • Python自動(dòng)化實(shí)現(xiàn)Excel文件與CSV文件的互相轉(zhuǎn)換

    Python自動(dòng)化實(shí)現(xiàn)Excel文件與CSV文件的互相轉(zhuǎn)換

    本文將深入探討如何利用Python,特別是借助spire.xls for python庫(kù),實(shí)現(xiàn)Excel文件到CSV文件的自動(dòng)化轉(zhuǎn)換,有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-09-09
  • Python如何讀取PDF文檔(或TXT)

    Python如何讀取PDF文檔(或TXT)

    這篇文章主要介紹了Python如何讀取PDF文檔(或TXT),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 以SortedList為例詳解Python的defaultdict對(duì)象使用自定義類型的方法

    以SortedList為例詳解Python的defaultdict對(duì)象使用自定義類型的方法

    這篇文章主要介紹了以SortedList為例詳解Python的defaultdict對(duì)象使用自定義類型的方法,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-07-07
  • python獲取txt文件詞向量過(guò)程詳解

    python獲取txt文件詞向量過(guò)程詳解

    這篇文章主要介紹了python獲取txt文件詞向量過(guò)程詳解,如何讀取完整的大文件,而不會(huì)出現(xiàn)內(nèi)存不足memery error等問(wèn)題,將讀取出來(lái)的文件,保存為npy文件,根據(jù)詞找到對(duì)應(yīng)的向量,需要的朋友可以參考下
    2019-07-07

最新評(píng)論

新沂市| 永年县| 长岛县| 晋城| 汉沽区| 金川县| 句容市| 楚雄市| 军事| 青阳县| 宁明县| 开原市| 巴南区| 临泽县| 洪湖市| 沙雅县| 汤阴县| 桃园市| 高密市| 获嘉县| 合山市| 荆州市| 石棉县| 江达县| 石楼县| 台东市| 乌拉特中旗| 荥经县| 正宁县| 广宗县| 崇明县| 乌拉特后旗| 漠河县| 平顺县| 家居| 吉木乃县| 永济市| 女性| 湟源县| 东兴市| 望城县|