我正在尝试编写一个客户端 - 服务器程序,其中服务器接收对数据库记录或文件的请求,然后将其发回。一切都工作得很好,直到我使用pickle函数从客户端发送数据到服务器,
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
self.run()
File "server.py", line 71, in run
data = pickle.loads(data)
File "/usr/lib/python2.7/pickle.py", line 1381, in loads
file = StringIO(str)
TypeError: expected read buffer, NoneType found
当我从服务器向客户端发送数据时,没有问题。我这样工作了几个星期但是当有大约50个例外时,服务器程序关闭了。
import socket
import sys
import time
import pickle
import struct
def recvall(sock, n):
# Helper function to recv n bytes or return None if EOF is hit
data = ''
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data += packet
return data
def recv_msg(sock):
# Read message length and unpack it into an integer
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return recvall(sock, msglen)
def sending(msg):
host = 'localhost'
port = 50000
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
lenght = len(msg)
if lenght>0:
msg = pickle.dumps(msg)
msg = struct.pack('>I', len(msg)) + msg
s.sendall(msg)
print 'sended string lenght: '+str(lenght)
else:
s.send('nothing sended')
data = recv_msg(s)
lenght2 = len(data)
print data
print 'received string lenght: '+str(lenght2)
#sys.stdout.write(data)
s.close()
while 1:
msg = raw_input('Input:')
sending(msg)
class Client(threading.Thread):
def __init__(self,(client,address)):
threading.Thread.__init__(self)
self.client = client
self.address = address
self.size = 1024
def run(self):
running = 1
while running:
sock = self.client
data = self.recv_msg(sock)
data = pickle.loads(data)
if data:
msg = struct.pack('>I', len(data)) + data
self.client.sendall(msg)
else:
self.client.close()
running = 0
def recv_msg(self, sock):
# Read message length and unpack it into an integer
raw_msglen = self.recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return self.recvall(sock, msglen)
def recvall(self, sock, n):
# Helper function to recv n bytes or return None if EOF is hit
data = ''
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data += packet
return data
在之前的版本中,我将pickle功能从服务器发送到客户端,它工作正常,没有任何问题,但现在我开始从头开始编写它以找到问题,但我没有。 在这里找到了recv_msg方法: Python Socket Receive Large Amount of Data
答案 0 :(得分:1)
当达到EOF时,recv_msg
方法会返回None
,并且您将None
传递给pickle.loads
,这是一个错误。
要解决此问题,请在 EOF检查后拨打pickle.loads()
:
data = self.recv_msg(sock)
if data is not None:
data = pickle.loads(data)
msg = struct.pack('>I', len(data)) + data
self.client.sendall(msg)
else:
self.client.close()
running = 0