我在Python3.4中编写了一个用于读取数据的简单套接字客户端
我遇到的问题是,当服务器发送少量数据(大约1000
)字节时,它会完美地读取它,但当处理大量数据(9500
字节)时,它只会给我一小块数据(比如1100-ish
块)。我似乎不明白为什么它在处理大量数据时表现得如此反复无常。我知道我的数据不会大于32767
的ssize_t
最大值。
它在处理小数据时工作得很好,在处理大量数据时表现完全不同。我知道这在TCP服务器中不是问题,因为我用PHP TCP客户机对它进行了测试,在处理大量数据时它工作得很好。
任何帮助都是非常感谢的。
import socket
import json
# Written in Python 3.4.
class SocketClient:
def __init__(self, host, port, format, timeout = None):
# Constructor
self.host = host
self.port = port
self.format = format
self.timeout = timeout
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def send(self, firstname, lastname, parameters = [], format = 'json'):
if self.socket is not None:
self.socket.connect((self.host, self.port))
data = {}
data['firstname'] = firstname
data['lastname'] = lastname
data['parameters'] = parameters
data['format'] = format
self.socket.send(bytes(json.dumps(data), "utf-8"))
result = self.socket.recv(32767)
result = result.decode()
return result
def shutdown(self):
if socket is not None:
self.socket.shutdown(socket.SHUT_RDWR)
self.socket.close()
if __name__ == __main__:
client = SocketClient("127.0.0.1", 8080, 'json')
response = client.send('foo', 'bar', ['foobar'])
print(response)
client.shutdown()
发布于 2014-05-18 00:52:33
TCP是一种流协议。数据是以字节垃圾的形式传输的,其中长度由许多因素决定。其一,内部缓冲区被限制为几千字节。你永远不可能一次读取32767个字节。使用recv
的唯一保证是,您至少获得1个字节,最多不超过您所说的字节数。您的代码必须处理此问题,这意味着您必须执行多个recv
调用,直到您拥有所需的字节数。这意味着在另一方面,没有消息结束指示符或长度编码的协议是严重破坏的。在本例中:您必须解析json字节流,直到发送了有效的json表达式。但是1245.6
呢?在接收到1
或12
或...之后完成了吗?要修复协议,只需将一些长度信息与json数据一起发送即可。
对于发送,你应该使用sendall
而不是send
。
发布于 2014-05-18 00:42:48
这就是recv在不止一种语言中的工作方式。https://docs.python.org/3.4/library/socket.html#socket.socket.recv
发布于 2019-04-01 07:06:14
您可以使用recv_into(buffer[, nbytes[, flags]])
方法:
def readReliably(s,n):
buf = bytearray(n)
view = memoryview(buf)
sz = 0
while sz < n:
k = s.recv_into(view[sz:],n-sz)
sz += k
# print 'readReliably()',sz
return sz,buf
def writeReliably(s,buf,n):
sz = 0
while sz < n:
k = s.send(buf[sz:],n-sz)
sz += k
# obj = s.makefile(mode='w')
# obj.flush()
# print 'writeReliably()',sz
return sz
查看完整示例:https://stackoverflow.com/a/55446223/966789
while True:
sk,skfrom = s.accept()
sz,buf = io.readReliably(sk,4)
a = struct.unpack("4B",buf)
print repr(a)
# ...
io.writeReliably(sk,struct.pack("4B",*[0x01,0x02,0x03,0x04]))
https://stackoverflow.com/questions/23713685
复制相似问题