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客户端的开发流程画成了图,方便你记忆。

TCP客户端开发流程 1. 创建socket 2. connect连接 3. send发送数据 4. recv接收数据 5. close关闭

2.8 避坑指南——我当年犯过的错

常见错误 后果 解决办法
忘记 encode/decode TypeError: 字符串不能直接发送 发送时 encode,接收时 decode
connect 地址写错 ConnectionRefusedError 检查IP和端口,用 ping 测试连通性
recv 缓冲区太小 数据接收不完整 循环接收,或者用更大的缓冲区
忘记 close 资源泄漏,端口被占用 用 try...finally 确保关闭
我的调试小技巧:如果客户端连不上服务器,先用 telnet 服务器IP 端口 测试一下。如果telnet能连上,说明网络没问题,问题出在代码里。如果telnet都连不上,那就先排查网络和服务器。

好了,TCP客户端开发的核心内容就这些。说白了就是五步:创建、连接、发送、接收、关闭。你把这个流程刻在脑子里,以后写任何TCP客户端都不会慌。

可可精品资料库