因此,我正在尝试将代码从Python 2.7转换为Python 3,似乎有些变化。我正在尝试通过套接字接收二进制数据,但现在不起作用。这是我的代码。
编辑:我已经添加了我的发送代码。另外,我真的不喜欢它现在的工作方式,它太复杂了。如果可以的话,最好有一种更好的发送/接收数据的方法。
def recv(self):
# Receive the length of the incoming message (unpack the binary data)
dataLength = socket.ntohl(struct.unpack("I", self._recv(4))[0])
# Receive the actual data
return self._recv(dataLength)
def _recv(self, length):
try:
data = ''
recvLen = 0
while recvLen < length:
newData = self.sock.recv(length-recvLen)
if newData == '':
self.isConnected = False
raise exceptions.NetworkError(errors.CLOSE_CONNECTION, errno=errors.ERR_CLOSED_CONNECTION)
data = data + newData # TypeError here
recvLen += len(newData)
return data
except socket.error as se:
raise exceptions.NetworkError(str(se))
def send(self, data):
if type(data) is not str:
raise TypeError()
dataLength = len(data)
# Send the length of the message (int converted to network byte order and packed as binary data)
self._send(struct.pack("I", socket.htonl(dataLength)), 4)
# Send the actual data
self._send(data, dataLength)
def _send(self, data, length):
sentLen = 0
while sentLen < length:
try:
amountSent = self.sock.send(data[sentLen:])
except Exception:
self.isConnected = False
raise exceptions.NetworkError(errors.UNEXPECTED_CLOSE_CONNECTION)
if amountSent == 0:
self.isConnected = False
raise exceptions.NetworkError(errors.UNEXPECTED_CLOSE_CONNECTION)
sentLen += amountSent
最佳答案
Python 3以字节为单位发送数据,因此您必须解码为字符串
data = data + newData.decode('utf-8')
# or
data = data + newData.decode('ascii')
如果您需要字节数据,请使用
data = b''
并保持没有
.decode()
data = data + newData
编辑:用于有疑问的新代码。
发送时,必须将字符串转换/编码为字节,然后再获取其长度。 native 字符的Unicode长度为1,但可以使用2个字节(或更多个字节)。
收到消息后,您必须使用
b''
字节,最后再将字节转换/解码为字符串。查看代码中的
# <--
注释def send(self, data):
if not isinstance(data, str): # <-- prefered method
#if type(data) is not str:
raise TypeError()
data = data.encode('utf-8') # <-- convert to bytes
# get size of bytes
dataLength = len(data)
# Send the length of the message (int converted to network byte order and packed as binary data)
self._send(struct.pack("I", socket.htonl(dataLength)), 4)
# Send the actual data
self._send(data, dataLength)
def recv(self):
# Receive the length of the incoming message (unpack the binary data)
dataLength = socket.ntohl(struct.unpack("I", self._recv(4))[0])
# Receive the actual data
return self._recv(dataLength).decode('utf-8') # <-- convert to string again
def _recv(self, length):
try:
data = b'' # <-- use bytes
recvLen = 0
while recvLen < length:
newData = self.sock.recv(length-recvLen)
#if newData == b'': # <-- use bytes
if not newData: # <-- or
self.isConnected = False
raise exceptions.NetworkError(errors.CLOSE_CONNECTION, errno=errors.ERR_CLOSED_CONNECTION)
data = data + newData # TypeError here
recvLen += len(newData)
return data
except socket.error as se:
raise exceptions.NetworkError(str(se))