Python Socket 编程常见问题与解决方案

我用 UDP 发送的时候明明就是发送是 16 进制的字节数据,如下:
-------
\x68\x74\x74\x70\x3A\x2F\x2F\x65\x77\x61\x74\x63\x68\x2E\x73\x63\x69\x66\x69\x6E\x65\x2E\x63\x6E\x2F\x61\x70\x69\x2F\x76\x31\x2E\x30\x2E\x30\x2F\x75\x70\x64\x61\x74\x65
-------
在 recvfrom 数据的时候:就是给我直接转换成字母了,我就要原生的数据咋办?
Python Socket 编程常见问题与解决方案


8 回复

编码解码问题吧


Python Socket 编程常见问题与解决方案

Socket编程是网络通信的基础,但在Python中常会遇到一些典型问题。这里我总结几个最常见的问题及其解决方案。

1. 地址已在使用 (Address already in use) 这通常是因为之前的连接没有正确关闭,端口处于TIME_WAIT状态。解决方案是设置SO_REUSEADDR选项:

import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('localhost', 8080))

2. 连接被拒绝 (Connection refused) 检查目标主机和端口是否正确,确保服务器端程序正在运行。客户端代码示例:

import socket

try:
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(('localhost', 8080))
    print("连接成功")
except ConnectionRefusedError:
    print("连接被拒绝,请检查服务器是否运行")

3. 数据发送不完整 TCP是流式协议,需要处理数据边界。使用固定长度或分隔符:

# 发送端
data = "Hello World"
client.sendall(f"{len(data):<10}".encode() + data.encode())

# 接收端
def recv_all(sock, n):
    data = b''
    while len(data) < n:
        packet = sock.recv(n - len(data))
        if not packet:
            return None
        data += packet
    return data

length_data = sock.recv(10)
if length_data:
    length = int(length_data.decode().strip())
    data = recv_all(sock, length)

4. 阻塞和非阻塞模式 默认情况下socket是阻塞的。设置非阻塞模式:

sock.setblocking(False)
# 或者
sock.settimeout(5.0)  # 设置超时

5. 处理多个连接 使用select模块处理多个客户端:

import select

read_sockets, _, _ = select.select([server_socket] + clients, [], [])
for sock in read_sockets:
    if sock == server_socket:
        client, addr = server_socket.accept()
        clients.append(client)
    else:
        data = sock.recv(1024)
        if data:
            # 处理数据
            pass
        else:
            sock.close()
            clients.remove(sock)

6. Unicode编解码问题 始终明确指定编码:

# 发送
data = "你好世界"
sock.sendall(data.encode('utf-8'))

# 接收
received = sock.recv(1024).decode('utf-8')

7. 资源泄漏 确保正确关闭连接:

try:
    sock = socket.socket()
    # ... 操作代码
finally:
    sock.close()

# 或者使用with语句
with socket.socket() as sock:
    sock.connect(('localhost', 8080))
    # ... 操作代码

总结建议: 理解TCP流特性和正确处理连接生命周期是关键。

在转成 16 进制😏

我用的 python3,感谢您的回复,问题是这样的,这个数据里面有隐藏的信息要提取,第一:这个数据就要 16 进制的,不要转成字母,第二:我转回 16 进制之后\x 就没了,如果没有\x,我怎么区分\x68\x74 还是\x6874。

我用的 python3,感谢您的回复,问题是这样的,这个数据里面有隐藏的信息要提取,第一:这个数据就要 16 进制的,不要转成字母,第二:我转回 16 进制之后\x 就没了,如果没有\x,我怎么区分\x68\x74 还是\x6874。

[hex(ord(x)) for x in your_data]

不用 struct.unpack ?

你到底是 bytes 还是 unicode ?
bytes 的话不存在 \x??? 这种四位的。并且 b’\x68’ == b’h’,在内存中是一样的,只是表达方式( repr )的不同。
还是说你想要传的数据应该是 rb’\x68’?

回到顶部