python - 无法弄清楚如何通过套接字发送 2D 数组 - OSError : [WinError 10022]

标签 python python-3.x windows sockets pickle

我正在尝试通过套接字发送一个二维数组,它需要由多个 socket.recv() 组成,否则我会得到一个 _pickle.UnpicklingError: pickle data was truncated错误。

我尝试使用接收数据包并将它们附加到列表中的 while 循环来执行此操作,直到收到所有数据:

def receive(self):
    packets = []
    while True:
        packet = self.socket.recv(1024)
        if not packet:
            break
        packets.append(packet)

    data = b"".join(packets)
    data = pickle.loads(data)
    return data

只是在做:
def receive(self):
    data = self.socket.recv(1024)
    data = pickle.loads(data)
    return data

如果我发送小于二维数组的东西,例如坐标对元组 (2, 3)。但不是二维数组。

我得到一个 OSError: [WinError 10022]在尝试 while 循环方法时。
我看到一个 OSError: [WinError 10022]不绑定(bind)套接字可能是个问题,但我想我已经做到了。
我无法弄清楚连接在哪里关闭并且很困惑。

其余代码:

服务器:
import socket
from _thread import start_new_thread

clients = []


def threaded(client):
    while True:
        data = client.recv(1024)
        if not data:
            print('Not Data.')
            break

        # Send the data received from one client to all the other clients.
        for c in clients:
            if c != client:
                c.send(data)

    client.close()


def Main():
    host = ""
    port = 5555
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((host, port))
    print("Socket binded to port:", port)

    s.listen(2)
    print("Socket is listening.")

    while True:
        c, addr = s.accept()
        clients.append(c)

        print(f"Connected to: {addr[0]}:{addr[1]}")

        start_new_thread(threaded, (c,))

    s.close()

客户:
import socket
import pickle


class Client:
    def __init__(self):
        self.host = 'localhost'
        self.port = 5555
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect((self.host, self.port))

    def send(self, data):
        message = pickle.dumps(data)
        try:
            self.socket.send(message)
        except socket.error as e:
            return str(e)

    def receive(self):
        packets = []
        while True:
            packet = self.socket.recv(1024)
            if not packet:
                break
            packets.append(packet)

        data = b"".join(packets)
        data = pickle.loads(data)
        return data

我要制作的客户端-服务器将有 2 个客户端,每个客户端都会不断地向另一个客户端发送数据。如何更正我的代码并正确实现?

最佳答案

在做了更多的研究并弄清楚出了什么问题后,我得到了解决方案。

代码从未退出这个 while 循环——因为数据不断被发送,并且总是有一些数据包传入。

def receive(self):
    packets = []
    while True:
        packet = self.socket.recv(1024)
        if not packet:
            break
        packets.append(packet)

我发现的一个解决方案是发送一条消息,指示接收到的消息应该有多大,这样我就可以知道特定消息的所有字节何时到达。链接:Sockets Python 3.5: Socket server hangs forever on file receive , Python Socket Receive Large Amount of Data
def send(self, data):
    message = pickle.dumps(data)
    msg_len = len(message)
    try:
        # Send what the total length of the message to be sent is in bytes.
        self.socket.send(msg_len.to_bytes(4, 'big'))
        self.socket.sendall(message)
    except socket.error as e:
        return str(e)

def receive(self):
    remaining = int.from_bytes(self.socket.recv(4), 'big')
    chunks = []
    while remaining:
        # until there are bytes left...
        # fetch remaining bytes or 4096 (whatever smaller)
        chunk = self.socket.recv(min(remaining, 4096))
        remaining -= len(chunk)
        # write to file
        chunks.append(chunk)

    chunks = b"".join(chunks)
    data = pickle.loads(chunks)
    return data

关于python - 无法弄清楚如何通过套接字发送 2D 数组 - OSError : [WinError 10022],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60893143/

相关文章:

python - 从列表中删除所有非数字

c++ - 确定窗口恢复大小

.net - 我的程序需要管理员权限才能打开文件是否正常?

windows - 如何从 Python 使用 cmd.exe 打开程序?

python - pymouse.click 不与其他软件交互

python - 如何让列表中的随机值在 Python 中列表中的每个值至少具有给定数量的唯一性?

c# - Windows 上的 Java 需要记录 CPU 负载和类似的操作系统特定性能信息

python - 如何在 python 中读取/理解 PHP 序列化数据字符串

python - 刷新 GUI 窗口

python - 以奇怪的角度发射的子弹pygame