
一、socket 简介Socket 又称套接字是应用程序与网络传输层之间的接口所有网络通信都基于 Socket。Python 内置socket模块无需额外安装可以直接完成 TCP、UDP 通信。网络两大传输协议TCPSOCK_STREAM面向连接、可靠、三次握手不会丢包。UDPSOCK_DGRAM无连接、不可靠直接发送数据包速度更快。导入模块importsocket二、socket 对象创建语法socket.socket(family,type)familysocket.AF_INETIPv4最常用typesocket.SOCK_STREAMTCPtypesocket.SOCK_DGRAMUDP示例# 创建TCP套接字tcp_socksocket.socket(socket.AF_INET,socket.SOCK_STREAM)# 创建UDP套接字udp_socksocket.socket(socket.AF_INET,socket.SOCK_DGRAM)第一部分TCP 通信全套APITCP通信分为客户端和服务端。1. TCP 客户端常用方法方法作用connect((host, port))和服务端建立TCP连接send(bytes)发送字节数据recv(buffer_size)接收数据返回bytessettimeout(n)设置阻塞超时时间close()关闭套接字完整客户端代码importsocket socksocket.socket(socket.AF_INET,socket.SOCK_STREAM)sock.settimeout(5)# 5秒无响应则超时# 建立连接sock.connect((127.0.0.1,8080))# 发送数据只能发送bytessock.send(你好服务端.encode(utf-8))# 接收数据最多读取1024字节datasock.recv(1024)print(data.decode(utf-8))sock.close()2. TCP 服务端常用方法方法作用bind((ip, port))绑定本机IP与端口listen(n)开启监听n为等待队列长度accept()阻塞等待客户端接入返回(conn, address)完整服务端代码importsocket serversocket.socket(socket.AF_INET,socket.SOCK_STREAM)# 端口复用避免重启时报端口被占用server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)server.bind((0.0.0.0,8080))server.listen(5)print(服务端已启动等待连接...)# 阻塞等待客户端conn,client_addrserver.accept()print(客户端地址,client_addr)# 接收消息msgconn.recv(1024)print(收到,msg.decode())# 回复消息conn.send(收到消息.encode(utf-8))# 关闭当前客户端连接conn.close()第二部分UDP 通信全套APIUDP 不需要建立连接没有connect可选核心方法只有两个方法作用sendto(data, (ip, port))发送数据并指定目标地址recvfrom(buffer)接收数据同时获取发送方地址1. UDP客户端只发数据importsocket socksocket.socket(socket.AF_INET,socket.SOCK_DGRAM)# 发送UDP数据包sock.sendto(b心跳包,(127.0.0.1,9999))sock.close()2. UDP服务端接收数据importsocket socksocket.socket(socket.AF_INET,socket.SOCK_DGRAM)sock.bind((0.0.0.0,9999))whileTrue:data,addrsock.recvfrom(1024)print(f来自{addr}:{data.decode()})# 回包sock.sendto(bok,addr)3. UDP广播设置局域网设备发现必备# 开启广播权限sock.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)sock.sendto(bonline,(255.255.255.255,9999))三、socket 高频通用配置选项1. 端口复用必加解决服务端重启提示Address already in usesock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)2. 设置阻塞超时recv、accept默认永久阻塞必须加超时防止程序卡死sock.settimeout(3)捕获异常try:datasock.recv(1024)exceptsocket.timeout:print(接收超时)3. 关闭Nagle算法小包立即发送sock.setsockopt(socket.IPPROTO_TCP,socket.TCP_NODELAY,True)4. 获取本机IPsocket.gethostbyname(socket.gethostname())5. 域名解析为IPsocket.gethostbyname(www.baidu.com)四、TCP 经典问题粘包问题TCP是字节流没有数据包边界多次发送的数据会粘在一起。解决方案固定每条消息长度先发送数据长度再发送正文使用换行符、特殊字符做分隔。简单分隔示例# 发送端sock.send(bhello|||)# 接收端按分隔符切割数据五、常用实战小案例案例1TCP端口存活检测defport_check(host,port,timeout2):try:socksocket.socket()sock.settimeout(timeout)sock.connect((host,port))sock.close()returnTrueexcept:returnFalse案例2裸Socket发送HTTP请求不使用requestssocksocket.socket()sock.connect((www.baidu.com,80))http_headerbGET / HTTP/1.1\r\nHost:www.baidu.com\r\nConnection:close\r\n\r\nsock.send(http_header)print(sock.recv(4096).decode(utf-8,errorsignore))sock.close()六、核心方法汇总表TCP专用connect()listen()bind()accept()send()recv()UDP专用sendto()recvfrom()公共方法settimeout()setsockopt()close()七、避坑总结所有收发数据必须是bytes字符串必须.encode(utf-8)TCP必须先连接再收发UDP直接发包recv缓冲区要合理设置太小会读不全数据一定要设置超时避免无限阻塞服务端绑定0.0.0.0才能对外网与局域网开放绑定127.0.0.1仅本机访问短连接收发完毕及时close避免大量TIME_WAIT占用端口。如果你需要我可以继续写多线程TCP服务端asyncio异步socket并发探测自定义TCP分包协议解决粘包完整版代码。