查看: 110|回复: 3

Python socket库TCP编程:端口检测、原始HTTP请求与长连接实践

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
本文基于Python内置socket库,不依赖任何第三方库,从零实现TCP客户端与服务端通信,涵盖短连接、长连接、端口存活检测、原始HTTP请求以及常见踩坑点。

一、TCP与UDP核心区别
TCP是面向连接的可靠传输协议:需要三次握手建立连接,保证数据有序不丢失;UDP直接发包,不保障送达。编程时TCP使用SOCK_STREAM,UDP使用SOCK_DGRAM。TCP适合文件传输、接口调用;UDP适合广播、实时流。

二、基础TCP客户端:短连接请求
短连接指连接建立后收发一次数据立即关闭。
核心方法:socket()创建套接字,connect()连接服务端,send()发送字节数据,recv()接收数据。
  1. import socket
  2. client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  3. host = "127.0.0.1"
  4. port = 9000
  5. try:
  6.     client.connect((host, port))
  7.     client.send("Hello TCP Server".encode("utf-8"))
  8.     recv_data = client.recv(1024)
  9.     print("收到服务端返回:", recv_data.decode("utf-8"))
  10. except ConnectionRefusedError:
  11.     print("端口未开放,TCP连接失败")
  12. finally:
  13.     client.close()
复制代码

三、TCP服务端:监听端口并处理连接
服务端固定端口监听,等待客户端接入。
关键函数:bind()绑定IP和端口,listen()开启监听,accept()阻塞等待新客户端。
  1. import socket
  2. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  3. server.bind(("0.0.0.0", 9000))
  4. server.listen(5)
  5. print("TCP服务端已启动,监听9000端口")
  6. while True:
  7.     conn, addr = server.accept()
  8.     print(f"新客户端接入:{addr}")
  9.     data = conn.recv(1024)
  10.     print("收到消息:", data.decode())
  11.     conn.send("消息已收到".encode("utf-8"))
  12.     conn.close()
复制代码
运行顺序:先启动服务端,再运行客户端。

四、TCP长连接:不断开持续收发数据
短连接每次都要重新握手,开销大;长连接建立一次连接,反复收发多条消息。

客户端长连接代码:
  1. import socket
  2. client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  3. client.connect(("127.0.0.1", 9000))
  4. for i in range(3):
  5.     msg = f"第{i+1}条消息".encode("utf-8")
  6.     client.send(msg)
  7.     res = client.recv(1024)
  8.     print("接收:", res.decode())
  9. client.close()
复制代码

服务端改造,持续读取数据:
  1. import socket
  2. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  3. server.bind(("0.0.0.0", 9000))
  4. server.listen(5)
  5. while True:
  6.     conn, addr = server.accept()
  7.     print("客户端已连接")
  8.     while True:
  9.         data = conn.recv(1024)
  10.         if not data:
  11.             break
  12.         print(data.decode())
  13.         conn.send("ok".encode())
  14.     conn.close()
复制代码
注意:客户端关闭连接后,服务端recv会拿到空字节,据此退出内层循环。

五、实战场景1:TCP端口存活检测
运维常用场景:批量探测服务器端口是否开放,本质就是尝试建立TCP连接。
  1. import socket
  2. def check_tcp_port(host, port, timeout=2):
  3.     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  4.     sock.settimeout(timeout)
  5.     try:
  6.         sock.connect((host, port))
  7.         return True, "端口开放"
  8.     except Exception:
  9.         return False, "端口关闭或无法连接"
  10.     finally:
  11.         sock.close()
  12. print(check_tcp_port("www.baidu.com", 80))
  13. print(check_tcp_port("127.0.0.1", 9999))
复制代码
此探测比UDP更可靠,广泛用于内网资产扫描、节点健康检测。

六、实战场景2:手动发送原始HTTP报文(裸TCP访问网页)
HTTP是构建在TCP之上的应用层协议,可以直接用TCP套接字发送HTTP报文,无需requests:
  1. import socket
  2. client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  3. client.connect(("www.baidu.com", 80))
  4. http_msg = b"GET / HTTP/1.1\r\nHost: www.baidu.com\r\nConnection: close\r\n\r\n"
  5. client.send(http_msg)
  6. response = client.recv(4096)
  7. print(response.decode("utf-8", errors="ignore"))
  8. client.close()
复制代码
运行即可获取百度HTTP响应头和网页正文,直观理解HTTP是如何封装在TCP之上的。

七、常见问题与避坑指南
- recv阻塞卡死:默认无限等待,可调用sock.settimeout(3)设置超时。
- TCP粘包问题:TCP是流式字节流,无数据包边界。自定义通信协议时必须加长度或分隔符。
- TIME_WAIT端口占用:程序务必正常close;服务端可开启端口复用:server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- 数据必须为bytes字节串:字符串发送前必须encode(),不能直接发送str。
- 单线程服务端只能处理一个客户端:高并发场景需要搭配多线程/多协程处理每条连接。

八、总结
TCP核心流程:创建套接字 → connect建立连接 → send/recv收发数据 → close断开。短连接一发一关,长连接复用TCP通道减少握手开销。原生Socket可实现端口探测、自定义报文、裸HTTP请求。掌握裸Socket通信,才能真正理解互联网数据传输的底层逻辑。
回复

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python socket库TCP编程:端口检测、原始HTTP请求与长连接实践

楼主写得很详细,把短连接、长连接、端口检测和原始HTTP请求都讲透了,而且全程只用socket标准库,实践性很强。特别是长连接那部分,很多人刚上手容易忽略服务端recv空字节的判断,这里特意点出来了,很实用。我之前用requests库习惯了,没想到直接用TCP发HTTP报文也能这么简单,回头试试搭配Connection: keep-alive做长连接实验。感谢分享!
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python socket库TCP编程:端口检测、原始HTTP请求与长连接实践

感谢楼主分享,非常实用的TCP编程教程,从短连接到长连接再到端口检测和原始HTTP请求,一步步讲得很清楚。特别是最后手动构造HTTP报文那部分,能帮初学者理解应用层和传输层的关系。补充一点:长连接场景下注意应用层需要自行处理粘包和半包问题,比如固定消息头或使用分隔符,楼主后续如果能再讲讲这个就更完美了。收藏了,以后做底层调试时直接参考。
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python socket库TCP编程:端口检测、原始HTTP请求与长连接实践

感谢楼主的详细教程!正好最近在学Python socket,这篇从短连接到长连接讲得很清晰,尤其是端口检测和手动发HTTP请求的实战例子很实用。之前一直用requests库,没想到直接用socket也能发HTTP报文,对底层原理理解帮助很大。另外想请教一下,长连接中如果服务端需要并发处理多个客户端,是每个客户端用一个单独线程处理,还是用select异步多路复用比较好?楼主有推荐的实践方案吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-29 10:50 , Processed in 0.035892 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部