Python socket库实现原生TCP请求

 更新时间:2026年06月29日 08:13:57   作者:detayun  
本文详细介绍了如何使用Python内置的socket库实现TCP客户端与服务端通信,涵盖短连接与长连接场景,并深入探讨了TCP与UDP的核心区别与实战应用,感兴趣的小伙伴可以了解下

一、前言

我们平时调用接口使用requests、aiohttp,底层全部都是TCP协议。HTTP只是构建在TCP之上的应用层协议。

很多运维、后端场景需要直接操作TCP裸连接:端口连通性探测、自定义报文通信、服务心跳、Socket长连接。

TCP是面向连接的可靠传输协议,通信分为三步:建立连接 → 收发数据 → 断开连接。

本文使用Python内置socket库,不依赖任何第三方库,从零实现TCP客户端与服务端通信。

二、TCP与UDP核心区别

  1. TCP需要先三次握手建立连接,UDP直接发包;
  2. TCP保证数据有序、不丢失;UDP只管发送,不保障送达;
  3. TCP使用SOCK_STREAM,UDP使用SOCK_DGRAM;
  4. TCP适合文件传输、接口调用;UDP适合广播、实时数据流。

三、基础TCP客户端:短连接请求

短连接:连接建立,收发一次数据,立刻关闭。

核心方法:

  • socket() 创建套接字
  • connect() 连接服务端IP端口
  • send() 发送字节数据
  • recv() 接收返回数据
import socket

# 创建TCP套接字 SOCK_STREAM = TCP
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 目标服务端地址
host = "127.0.0.1"
port = 9000

try:
    # 发起三次握手,建立TCP连接
    client.connect((host, port))
    # 发送二进制数据
    client.send("Hello TCP Server".encode("utf-8"))
    # 阻塞等待接收服务端返回数据,缓冲区1024字节
    recv_data = client.recv(1024)
    print("收到服务端返回:", recv_data.decode("utf-8"))
except ConnectionRefusedError:
    print("端口未开放,TCP连接失败")
finally:
    # 关闭连接,释放资源
    client.close()

四、TCP服务端:监听端口并处理连接

服务端固定端口监听,等待客户端接入。

关键函数:

  • bind() 绑定IP和端口
  • listen() 开启监听
  • accept() 阻塞等待新客户端接入
import socket

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定0.0.0.0,允许局域网所有设备访问
server.bind(("0.0.0.0", 9000))
# 开启监听,最大挂起队列5
server.listen(5)
print("TCP服务端已启动,监听9000端口")

while True:
    # 阻塞等待客户端连接
    conn, addr = server.accept()
    print(f"新客户端接入:{addr}")
    # 接收客户端消息
    data = conn.recv(1024)
    print("收到消息:", data.decode())
    # 回复数据
    conn.send("消息已收到".encode("utf-8"))
    # 关闭本次客户端连接(短连接模式)
    conn.close()

运行顺序:先启动服务端,再运行客户端,即可完成一次TCP通信。

五、TCP长连接:不断开持续收发数据

短连接每次通信都要重新握手,开销很大。长连接建立一次连接,反复收发多条消息。

客户端长连接代码

import socket

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

# 循环发送多条数据,连接不断开
for i in range(3):
    msg = f"第{i+1}条消息".encode("utf-8")
    client.send(msg)
    res = client.recv(1024)
    print("接收:", res.decode())

client.close()

服务端改造(持续读取数据)

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("客户端已连接")
    # 持续读取客户端消息
    while True:
        data = conn.recv(1024)
        if not data:
            # 客户端关闭连接,recv会拿到空字节
            break
        print(data.decode())
        conn.send("ok".encode())
    conn.close()

六、实战场景1:TCP端口存活检测

运维最常用场景:批量探测服务器端口是否开放,本质就是尝试建立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, "端口开放"
    except Exception:
        return False, "端口关闭或无法连接"
    finally:
        sock.close()

# 测试
print(check_tcp_port("www.baidu.com", 80))
print(check_tcp_port("127.0.0.1", 9999))

这个端口探测比UDP探测更加可靠,广泛用于内网资产扫描、节点健康检测。

七、实战场景2:手动发送原始HTTP报文(裸TCP访问网页)

HTTP协议就是文本TCP报文,我们不用requests,直接用TCP套接字访问网页:

import socket

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

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

# 接收网页响应
response = client.recv(4096)
print(response.decode("utf-8", errors="ignore"))
client.close()

运行就能拿到百度的HTTP响应头与网页正文,可以直观理解HTTP是封装在TCP之上的应用层协议。

八、TCP开发常见问题与避坑

recv阻塞卡死:recv默认无限等待,可以设置sock.settimeout(3)超时断开。

粘包问题:TCP是流式字节流,没有数据包边界,多条数据会黏在一起。自定义通信协议时,必须加数据长度分隔符。

客户端没有正常close,导致端口被占用(TIME_WAIT):程序一定要正常关闭套接字;服务端可以开启端口复用:

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

数据必须为bytes字节串:字符串一定要encode,不能直接发送str字符串。

单线程服务端只能处理一个客户端:上面的服务端是单线程,一次只能服务一个连接,高并发场景需要搭配多线程/多协程处理每一条TCP连接。

九、异步TCP(asyncio高级用法)

高并发大量TCP探测时,同步socket效率太低,可以使用asyncio创建异步TCP连接,上万条连接轻松调度,占用内存极低,非常适合批量端口巡检。

十、总结

  1. TCP核心流程:创建套接字 → connect建立连接 → send/recv收发数据 → close断开;
  2. 短连接一发一关,长连接复用TCP通道减少握手开销;
  3. 原生Socket TCP可以实现端口探测、自定义报文、裸HTTP请求;
  4. requests、urllib、爬虫框架底层全部都是对TCP Socket的封装。

原生TCP网络编程是后端、运维、网络爬虫的基本功,掌握裸Socket通信,才能真正理解互联网数据传输的底层逻辑。

如果你想,我可以再续写一版:多线程TCP服务端 + 异步批量TCP端口检测代码。

到此这篇关于Python socket库实现原生TCP请求的文章就介绍到这了,更多相关Python socket实现TCP请求内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解Scrapy Redis入门实战

    详解Scrapy Redis入门实战

    这篇文章主要介绍了详解Scrapy Redis入门实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • 在PyCharm中控制台输出日志分层级分颜色显示的方法

    在PyCharm中控制台输出日志分层级分颜色显示的方法

    今天小编就为大家分享一篇在PyCharm中控制台输出日志分层级分颜色显示的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-07-07
  • python如何实现excel数据添加到mongodb

    python如何实现excel数据添加到mongodb

    本文介绍了python是如何实现excel数据添加到mongodb,为了将数据导入mongodb,引入了pymongo,xlrd包,需要的朋友可以参考下
    2015-07-07
  • Python Matplotlib绘制箱线图boxplot()函数详解

    Python Matplotlib绘制箱线图boxplot()函数详解

    箱线图一般用来展现数据的分布(如上下四分位值、中位数等),同时也可以用箱线图来反映数据的异常情况,下面这篇文章主要给大家介绍了关于Python Matplotlib绘制箱线图boxplot()函数的相关资料,需要的朋友可以参考下
    2022-07-07
  • Python3简单实现串口通信的方法

    Python3简单实现串口通信的方法

    今天小编就为大家分享一篇Python3简单实现串口通信的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-06-06
  • 回归预测分析python数据化运营线性回归总结

    回归预测分析python数据化运营线性回归总结

    本文主要介绍了python数据化运营中的线性回归一般应用场景,常用方法,回归实现,回归评估指标,效果可视化等,并采用了回归预测分析的数据预测方法
    2021-08-08
  • Python自动化实现Excel文件与CSV文件的互相转换

    Python自动化实现Excel文件与CSV文件的互相转换

    本文将深入探讨如何利用Python,特别是借助spire.xls for python库,实现Excel文件到CSV文件的自动化转换,有需要的小伙伴可以跟随小编一起学习一下
    2025-09-09
  • Python如何读取PDF文档(或TXT)

    Python如何读取PDF文档(或TXT)

    这篇文章主要介绍了Python如何读取PDF文档(或TXT),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • 以SortedList为例详解Python的defaultdict对象使用自定义类型的方法

    以SortedList为例详解Python的defaultdict对象使用自定义类型的方法

    这篇文章主要介绍了以SortedList为例详解Python的defaultdict对象使用自定义类型的方法,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-07-07
  • python获取txt文件词向量过程详解

    python获取txt文件词向量过程详解

    这篇文章主要介绍了python获取txt文件词向量过程详解,如何读取完整的大文件,而不会出现内存不足memery error等问题,将读取出来的文件,保存为npy文件,根据词找到对应的向量,需要的朋友可以参考下
    2019-07-07

最新评论