2. TCP客户端开发:从零搭建你的第一个网络连接
好,咱们今天来聊聊TCP客户端开发。说实话,这是网络编程里最基础、也最实用的一块。我当年刚入行时,第一个正式项目就是写一个TCP客户端,用来采集设备数据。那时候踩了不少坑,今天我把这些经验都揉碎了讲给你听。
2.1 创建socket——网络通信的“门牌号”
要跟服务器说话,首先得有个“电话机”。这个电话机在Python里就叫socket。
import socket
# 创建一个TCP socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
这里两个参数什么意思?
AF_INET:指定使用IPv4地址。说白了,就是告诉系统我要用互联网协议第四版。SOCK_STREAM:指定使用TCP协议。流式传输,保证数据按顺序到达。
我的小习惯:创建socket时,我习惯把参数写成常量形式,而不是直接写数字。比如
socket.AF_INET 而不是 2。为什么?因为代码可读性更强,别人一看就懂。
2.2 connect连接——拨通服务器的电话
有了socket,接下来就是连接服务器。就像你拿起电话拨号一样。
server_address = ('192.168.1.100', 8888)
client_socket.connect(server_address)
这里传入的是一个元组:(IP地址, 端口号)。IP地址是服务器的门牌号,端口号是具体的房间号。
我曾经踩过的坑:有一次我写客户端,connect一直报错
ConnectionRefusedError。查了半天才发现,服务器根本没启动。所以记住:先确保服务器在监听,客户端再去连。不然就像你打电话过去,对方电话没插线。
2.3 send发送数据——把话说出去
连接建立后,就可以发送数据了。注意,TCP发送的是字节流,不是字符串。
message = "你好,服务器!"
client_socket.send(message.encode('utf-8'))
为什么要 encode?因为网络传输只认二进制,不认文字。你想想看,如果直接发字符串,服务器那边收到的是乱码,那不就尴尬了?
重要提醒:
send() 方法不一定一次就把所有数据发完。它返回实际发送的字节数。如果数据量大,需要循环发送。不过初学者阶段,小数据量一次发送基本没问题。
2.4 recv接收数据——听服务器怎么说
发完数据,通常要等服务器回复。这时候用 recv() 来接收。
response = client_socket.recv(1024)
print("服务器回复:", response.decode('utf-8'))
1024 是缓冲区大小,单位是字节。意思是:我一次最多接收1024个字节。如果服务器回复的数据超过1024字节,需要多次接收。
为什么会这样?因为TCP是流式协议,数据像水流一样过来。你拿一个杯子接水,杯子满了就得先倒掉,再接着接。
2.5 close关闭——用完记得挂电话
通信结束,一定要关闭socket。这就像打完电话挂断一样自然。
client_socket.close()
切记:不关闭socket会导致资源泄漏。我在项目中遇到过,一个同事写的客户端程序跑了一周,服务器上出现了几千个
TIME_WAIT 状态的连接。原因就是客户端没有正确关闭socket。后来我们加上了 try...finally 确保无论如何都会关闭。
2.6 完整示例——一个能跑起来的TCP客户端
把上面这些串起来,就是一个完整的TCP客户端。
import socket
def tcp_client():
# 1. 创建socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# 2. 连接服务器
server_addr = ('127.0.0.1', 8888)
client.connect(server_addr)
print(f"已连接到 {server_addr}")
# 3. 发送数据
data = "Hello, TCP Server!"
client.send(data.encode('utf-8'))
print(f"发送: {data}")
# 4. 接收回复
response = client.recv(1024)
print(f"收到: {response.decode('utf-8')}")
except Exception as e:
print(f"发生错误: {e}")
finally:
# 5. 关闭连接
client.close()
print("连接已关闭")
if __name__ == "__main__":
tcp_client()
2.7 核心流程一览
我把整个TCP客户端的开发流程画成了图,方便你记忆。
2.8 避坑指南——我当年犯过的错
| 常见错误 | 后果 | 解决办法 |
|---|---|---|
| 忘记 encode/decode | TypeError: 字符串不能直接发送 | 发送时 encode,接收时 decode |
| connect 地址写错 | ConnectionRefusedError | 检查IP和端口,用 ping 测试连通性 |
| recv 缓冲区太小 | 数据接收不完整 | 循环接收,或者用更大的缓冲区 |
| 忘记 close | 资源泄漏,端口被占用 | 用 try...finally 确保关闭 |
我的调试小技巧:如果客户端连不上服务器,先用
telnet 服务器IP 端口 测试一下。如果telnet能连上,说明网络没问题,问题出在代码里。如果telnet都连不上,那就先排查网络和服务器。
好了,TCP客户端开发的核心内容就这些。说白了就是五步:创建、连接、发送、接收、关闭。你把这个流程刻在脑子里,以后写任何TCP客户端都不会慌。
可可精品资料库