Python Socket

1. 服务端

想象现在是两个人通话所需要的步骤为:

步骤 Socket 动作 (函数) 电话场景描述
第一步 socket() 买手机:你得先有一台能通话的设备。
第二步 bind() 插手机卡:给这台手机绑定一个具体的电话号码(IP 和 端口)。
第三步 listen() 开机待机:确保手机有信号,坐等别人打进来。
第四步 connect() 拨号:客户端按下号码,呼叫服务端。
第五步 accept() 接听:听到铃响,按下接听键,通话链路建立。
第六步 send() / recv() 说话与听话:双方互相传递语音信息(字节数据)。
第七步 close() 挂断:聊完了,挂掉电话,释放线路。

1.1 socket(family, type , proto, fileno)

python 复制代码
def __init__(self, family=-1, type=-1, proto=-1, fileno=None):
    """
    socket 类的初始化方法
    :param family: 地址族 (Address Family)
    :param type: 套接字类型 (Socket Type)
    :param proto: 协议号 (Protocol Number)
    :param fileno: 文件描述符 (通常为 None,除非要封装一个现有的连接)
    """
    # 如果没有提供现有的文件描述符,则按照默认参数初始化
    if fileno is None:
        # 1. 确定【地址族】
        # 如果没有指定,默认使用 AF_INET (IPv4 网络通信)
        if family == -1:
            family = AF_INET  
            # AF_INET: 表示使用的是 IPv4 地址(如 127.0.0.1)
            # AF_UNIX: 表示本机进程间通信(像是在同一台电脑的文件系统内交流)

        # 2. 确定【传输类型】
        # 如果没有指定,默认使用 SOCK_STREAM (面向连接的流式传输)
        if type == -1:
            type = SOCK_STREAM  
            # SOCK_STREAM: 对应 TCP 协议(可靠、像打电话、有序)
            # SOCK_DGRAM:  对应 UDP 协议(不可靠、像发短信、速度快)

        # 3. 确定【协议】
        # 0 表示根据 family 和 type 自动选择合适的协议(通常就是这样)
        if proto == -1:
            proto = 0

    # 4. 调用底层 C 语言编写的 _socket 接口完成真正的创建工作
    _socket.socket.__init__(self, family, type, proto, fileno)

    # 5. 内部状态初始化
    self._io_refs = 0     # 引用计数:记录有多少个地方在使用这个 socket
    self._closed = False  # 状态位:标记这个"电话"是否已经挂断

1.2 bind(tuple)

为这个服务器指定运行时的IP地址和端口,tuple有两个元素,一个是ip地址,一个是端口号

1.3 listen()

服务器进入监听状态,此时可以接收客服端发起的请求

1.4 accept()

当有客户端发起请求时触发,会返回一个元组,第一个元素是新的连接对象,通过这个连接对象和对应的客户端通信;第二个元素是客户端的IP地址。

1.5 rece()和send()

发/收客户端发送的数据,都是二进制类型,因此需要encode和decode

1.6 close()

传输完毕,释放连接

1.7 完整服务端代码

python 复制代码
import socket

# 1. 【买手机】
# 创建一个 Socket 对象。
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# 2. 【办卡/定号码】
# 告诉操作系统:我要占用这个 IP 和 端口。
# 注意:参数是一个元组 (ip, port)
addr = '127.0.0.1' # 对方拨打的"区号"
port = 9999        # 对方拨打的"分机号"
server.bind((addr, port))

# 3. 【开启监听】
# 5 表示"等候室"的大小:如果同时有很多人打来,最多允许 5 个人排队。
server.listen(5)
print("手机已开机,信号满格,等待来电...")

# 4. 【有客户端连接】
# conn: 建立的具体通话链路(专门负责跟这一个人聊天)
# addr: 对方的手机号信息(客户端的 IP 和 端口)
conn, client_addr = server.accept()
print(f"电话接通了!对方的号码是: {client_addr}")

# 5. 【发送和接收】
# 接收消息 (recv):听对方说话,最多听 1024 字节。
data_from_client = conn.recv(1024)
print(f"对方说: {data_from_client.decode('utf-8')}")

# 发送消息 (send):对对方说话。
# 注意:网络传输必须是字节码,所以要用 .encode() 编码。
data_to_client = '收到了,信号很好!'
conn.send(data_to_client.encode('utf-8'))

# 6. 【挂断电话】
# 结束这次通话,释放这条线路。
conn.close()

# 7. 【关机】
# 彻底关闭服务端(通常生产环境下服务端是不关机的)。
server.close()

2. 客户端

步骤 Socket 动作 (函数) 电话场景描述
第一步 socket() 买手机:准备好通讯设备,并确认大家用同样的通讯协议(如 IPv4 和 TCP)。
第二步 connect() 拨号:输入对方的"电话号码"(IP 和 端口),主动发起呼叫。
第三步 send() / recv() 说话与听话:对方接听后,开始互相传递信息(注意要转换成字节数据)。
第四步 close() 挂断:聊完了,主动挂断电话,释放自己的线路资源。

2.1 socket()

和服务端一致,需要确保参数一致

2.2 conect()

像服务器申请连接,如果此时服务器未启动会报错

2.3 send()和recv()

和服务端一致

2.4 close()

和服务端一致

2.5 完整客户端代码

python 复制代码
import socket

# 1. 【买手机】
# 创建一个 Socket 对象。
# 必须和服务端约定好:大家都要用 IPv4 (AF_INET) 和 TCP (SOCK_STREAM)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 2. 【拨号】
# 这里的 IP 和 端口 必须是服务端正在"监听"的那个号码。
server_addr = '127.0.0.1'
server_port = 9999
# 注意:connect 同样接收一个元组
client.connect((server_addr, server_port))
print("连接服务器成功!开始通话...")

# 3. 【说话与听话】
# 发送消息 (send):先主动开口说话
msg = "你好,我是客户端,听到请回答!"
client.send(msg.encode('utf-8'))

# 接收消息 (recv):等对方回复
# 同样最多接收 1024 字节
data_from_server = client.recv(1024)
print(f"服务器回复了: {data_from_server.decode('utf-8')}")

# 4. 【挂断电话】
# 聊完之后,主动挂断连接
client.close()
print("通话结束,已挂断。")
相关推荐
码农水水2 小时前
京东Java面试被问:系统限流的实现方式
java·开发语言·面试
Sheep Shaun2 小时前
STL中的map和set:红黑树的优雅应用
开发语言·数据结构·c++·后端·c#
宁大小白2 小时前
pythonstudy Day45
开发语言·python·深度学习
Yu_iChan3 小时前
Day03 公共字段填充与菜品管理
java·开发语言
独自破碎E3 小时前
如何防止接口被恶意刷量?
java·开发语言
期待のcode3 小时前
Java的单例模式
java·开发语言·单例模式
Aliex_git3 小时前
内存堆栈分析笔记
开发语言·javascript·笔记
AI手记叨叨3 小时前
Python数学:统计运算
python·数学·统计运算·描述统计·概率运算
Brian Xia3 小时前
从0开始手写AI Agent框架:nano-agentscope(一)项目介绍
人工智能·python·ai