Python通过套接字发送和接收对象

Dha*_*dar -3 python sockets

我在网上搜索了很多但是找不到通过套接字发送对象并按原样接收它的解决方案.我知道它需要我已经做过的酸洗.并且将其转换为字节并且另一方面接收.但是如何将这些字节转换为该类型的对象.

        process_time_data = (current_process_start_time, current_process_end_time)
        prepared_process_data = self.prepare_data_to_send(process_time_data)
        data_string = io.StringIO(prepared_process_data)
        data_string =  pack('>I' ,len(data_string)) + data_string
        self.send_to_server(data_string)            
Run Code Online (Sandbox Code Playgroud)

这是将对象转换为客户端上的StringIO并发送到服务器的代码.在服务器端,我得到字节.现在我正在搜索要再次转换为StringIO的字节,以便我可以获取对象值.

在代码中,Object包装在StringIO中,并通过套接字发送.任何更好的方法将受到高度赞赏.

服务器端代码如下.

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#server.setblocking(0)
server.bind(('127.0.0.1',50000))
server.listen(5)
inputs = [server]
outputs = []
message_queues = {}

while inputs:
    readable, writeable, exceptional = select.select(inputs, outputs, inputs)
    for s in readable:
        if s is server:
            connection, client_address = s.accept()
            print(client_address)
            connection.setblocking(0)
            inputs.append(connection)
            message_queues[connection] = queue.Queue()
            print('server started...')
        else:
            print('Getting data step 1')
            raw_msglen = s.recv(4)
            msglen = unpack('>I',raw_msglen)[0]
            final_data = b''
            while len(final_data) < msglen:
                data = s.recv(msglen - len(final_data))
                if data:
                    #print(data)
                    final_data += data
                    message_queues[s].put(data)
                    if s not in outputs:
                        outputs.append(s)
                    else:
                        if s in outputs:
                            outputs.remove(s)
                else:
                    break
            inputs.remove(connection)
#            s.close()
            del message_queues[s]

            process_data = ProcessData()
            process_screen = ProcessScreen()

            if final_data is not None:
                try:
                    deserialized_data = final_data.decode("utf-8")
                    print(deserialized_data)
                except (EOFError):
                    break
            else:
                print('final data is empty.')

            print(process_data.project_id)
            print(process_data.start_time)
            print(process_data.end_time)
            print(process_data.process_id)
Run Code Online (Sandbox Code Playgroud)

两个辅助函数如下

def receive_all(server, message_length, message_queues, inputs, outputs):
    # Helper function to recv message_length bytes or return None if EOF is hit
    data = b''
    while len(data) < message_length:
        packet = server.recv(message_length - len(data))
        if not packet:
            return None
        data += packet
        message_queues[server].put(data)
        if server not in outputs:
            outputs.append(server)
        else:
            if server in outputs:
                outputs.remove(server)
    inputs.remove(server)
    del message_queues[server]
    return data


def receive_message(server, message_queues, inputs, outputs):
    # Read message length and unpack it into an integer
    raw_msglen = receive_all(server, 4, message_queues, inputs, outputs)
    if not raw_msglen:
        return None
    message_length = unpack('>I', raw_msglen)[0]

    return receive_all(server, message_length, message_queues, inputs, outputs)
Run Code Online (Sandbox Code Playgroud)

其中两个模型类如下

class ProcessData:
    process_id = 0
    project_id = 0
    task_id = 0
    start_time = 0
    end_time = 0
    user_id = 0
    weekend_id = 0

# Model class to send image data to the server
class ProcessScreen:
    process_id = 0
    image_data = bytearray()
Run Code Online (Sandbox Code Playgroud)

Sud*_*lla 15

什么你要找的是这里pickleloadsdumps操作.套接字基本上是字节流.让我们考虑你的情况.

class ProcessData:
    process_id = 0
    project_id = 0
    task_id = 0
    start_time = 0
    end_time = 0
    user_id = 0
    weekend_id = 0
Run Code Online (Sandbox Code Playgroud)

需要被腌制成做数据串这个类的一个实例data_string = pickle.dumps(ProcessData())做和拆封data_variable = pickle.loads(data)哪里data是收到什么.

因此,让我们考虑客户端创建对象ProcessData并将其发送到服务器的情况.这是客户端的样子.这是一个最小的例子.

客户

import socket, pickle

class ProcessData:
    process_id = 0
    project_id = 0
    task_id = 0
    start_time = 0
    end_time = 0
    user_id = 0
    weekend_id = 0


HOST = 'localhost'
PORT = 50007
# Create a socket connection.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

# Create an instance of ProcessData() to send to server.
variable = ProcessData()
# Pickle the object and send it to the server
data_string = pickle.dumps(variable)
s.send(data_string)

s.close()
print 'Data Sent to Server'
Run Code Online (Sandbox Code Playgroud)

现在,接收此数据的服务器如下所示

服务器

import socket, pickle

class ProcessData:
    process_id = 0
    project_id = 0
    task_id = 0
    start_time = 0
    end_time = 0
    user_id = 0
    weekend_id = 0


HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr

data = conn.recv(4096)
data_variable = pickle.loads(data)
conn.close()
print data_variable
# Access the information by doing data_variable.process_id or data_variable.task_id etc..,
print 'Data received from client'
Run Code Online (Sandbox Code Playgroud)

首先运行服务器bind在端口上创建一个,然后运行client通过套接字进行数据传输.你也可以看看这个答案

  • 你是什​​么意思,你运行它,它不起作用.你是如何运行单个文件的?你能打开两个终端,将上面的代码复制到相应的文件`server.py`和`client.py`中.在一个终端运行服务器,在另一个终端运行客户端 您将获得一个`<__ main __.ProcessData实例,位于0x10572edd0>`作为响应,它是您从客户端发送到服务器的`ProcessData`类的实例. (2认同)
  • @Bilkokuya 非常感谢。@Dharmindar 很高兴它有所帮助。不过,我想告诉你一些事情。您在上面的评论中提到了'而不是回应我的最后一条评论,您可以回答这个问题,或者可以说这是我不知道的。请理解我们不是在帮您一个忙,您不应该以这种方式与 stackoverflow 社区中的任何人交谈。祝你工作顺利。 (2认同)
  • 问题是因为限制了'4096`字节.你需要一个循环来接收所有数据,然后将`4096`字节块"连接"到你想要的字符串中.[这里](/sf/answers/2891105521/)就是一个例子.您可以在stackoverflow上轻松搜索这些内容.请不要指望我们写下所有内容. (2认同)