泡菜EOFError:从套接字接收时超出输入范围 [英] Pickle EOFError: Ran out of input when recv from a socket

查看:73
本文介绍了泡菜EOFError:从套接字接收时超出输入范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为学校项目(不打算用于现实世界)运行一个非常简单的python(3.x)客户端-服务器程序(均在我的PC上本地运行),该程序只是来回发送消息(如view)客户,添加客户,删除客户等...真正的基础.)

I am running a very simple python (3.x) client-server program (both locally on my PC) for a school project (not intended for the real world) which just sends messages back-and-forth (like view customers, add customer, delete customer, etc... real basic).

有时候数据可以是多个记录,这些记录我已经存储为namedTuples(很有意义),然后沿着使用Pickle进行传输的路径走了.

Sometimes the data can be multiple records which I had stored as namedTuples (just made sense) and then went down the path of using Pickle to transfer then.

例如,在客户端上,我做这样的事情:

So for example on the client I do something like this:

s.send(message.encode('utf-8'))
pickledResponse = s.recv(4096);
response = pickle.loads(pickledResponse)

现在我经常遇到以下错误:

Now ever so often I get the following error:

response = pickle.loads(pickledResponse)
EOFError: Ran out of input

我担心这与我的套接字(TCP)传输有关,也许不知为何我没有及时获取我的pickle.loads的所有数据-有意义吗?如果不是这样,我真的不知道为什么会如此不一致地发生.

My fear is that this has something to do with my socket (TCP) transfer and maybe somehow I am not getting all the data in time for my pickle.loads - make sense? If not I am really lost as to why this would be happening so inconsistently.

但是,即使我是对的,我也不知道如何(快速)解决它,我正在考虑丢下泡菜,只是使用琴弦(但这难道不会遭受同样的命运)吗?有人有什么建议吗?

However, even if I am right I am not sure how to fix it (quickly), I was considering dropping pickle and just using strings (but couldn't this suffer from the same fate)? Does anyone have any suggestions?

我的信息真的很基础-通常只是一个命令和一些小数据,例如"1 = John",这意味着命令(1)是FIND命令,然后是"John",它返回记录(名称,年龄等) ...)(作为namedTuple的名字-但老实说,这不是强制性的.)

Really my message are pretty basic - usually just a command and some small data like "1=John" which means command (1) which is FIND command and then "John" and it returns the record (name, age, etc...) of John (as a namedTuple - but honestly this isn't mandatory).

任何建议或帮助将不胜感激,寻找快速解决方案...

Any suggestions or help would be much appreciated, looking for a quick fix...

推荐答案

您的代码存在的问题是,recv(4096)在TCP套接字上使用时,可能会返回与您期望值不同的数据量,因为它们在数据包边界处被切片.

The problem with your code is that recv(4096), when used on a TCP socket, might return different amount of data from what you might have expected, as they are sliced at packet boundaries.

简单的解决方案是为每个消息添加长度;发送像

The easy solution is to prefix each message with length; for sending like

import struct
packet = pickle.dumps(foo)
length = struct.pack('!I', len(packet)
packet = length + packet

然后接收

import struct

buf = b''
while len(buf) < 4:
    buf += socket.recv(4 - len(buf))

length = struct.unpack('!I', buf)[0]
# now recv until at least length bytes are received,
# then slice length first bytes and decode.


但是,Python标准库已经支持面向消息的酸洗套接字,即


However, Python standard library already has a support for message oriented pickling socket, namely multiprocessing.Connection, that supports sending and receiving pickles with ease using the Connection.send and Connection.recv respectively.

因此您可以将服务器编码为

Thus you can code your server as

from multiprocessing.connection import Listener

PORT = 1234
server_sock = Listener(('localhost', PORT))
conn = server_sock.accept()

unpickled_data = conn.recv()

和客户

from multiprocessing.connection import Client

client = Client(('localhost', 1234))
client.send(['hello', 'world'])

这篇关于泡菜EOFError:从套接字接收时超出输入范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆