Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python TCP套接字在recv中丢失数据[行为怪异]_Python_Sockets_Tcp - Fatal编程技术网

Python TCP套接字在recv中丢失数据[行为怪异]

Python TCP套接字在recv中丢失数据[行为怪异],python,sockets,tcp,Python,Sockets,Tcp,我在Python3.4中编写了一个用于读取数据的简单套接字客户端 我遇到的问题是,当服务器发送少量数据(约为1000)字节时,它将完美地读取数据,但当处理大量数据时(9500字节),它只会给我一小块数据(如1100块)。我似乎不明白为什么它在处理大量数据时表现得如此不稳定。我知道我的数据不超过ssize\u t最大值32767 它在处理小数据时工作得很好,完全达到180度,在处理大量数据时表现不同。我知道这在TCP服务器中不是问题,因为我用PHPTCP客户机测试了它,它在处理大量数据时工作得非常

我在Python3.4中编写了一个用于读取数据的简单套接字客户端

我遇到的问题是,当服务器发送少量数据(约为
1000
)字节时,它将完美地读取数据,但当处理大量数据时(
9500
字节),它只会给我一小块数据(如
1100
块)。我似乎不明白为什么它在处理大量数据时表现得如此不稳定。我知道我的数据不超过
ssize\u t
最大值
32767

它在处理小数据时工作得很好,完全达到180度,在处理大量数据时表现不同。我知道这在TCP服务器中不是问题,因为我用PHPTCP客户机测试了它,它在处理大量数据时工作得非常好

非常感谢您的帮助

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()

这就是recv在多种语言中的工作原理

TCP是一种流协议。数据以字节为单位传递,长度由许多因素决定。一个是,内部缓冲区被限制在数千字节左右。您永远不能一次读取32767字节。 使用
recv
的唯一保证是,您至少可以得到1个字节,最多可以得到您所说的字节数。您的代码必须处理这个问题,这意味着您必须执行多个
recv
调用,直到获得所需的字节数。这意味着在另一方面,没有消息结束指示符或编码长度的协议被严重破坏。在您的例子中:您必须解析json字节流,直到发送有效的json表达式。但是
1245.6
呢?是否在收到
1
12
或。。。? 要修复协议,只需将一些长度信息与json数据一起发送即可


对于发送,您应该使用
sendall
而不是
send

您可以使用
recv_进入(缓冲区[,n字节[,标志])
方法:

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

我明白。。。但是,当你给它一个大的缓冲区时,为什么它在处理不同大小的数据时会表现得如此不同呢?你没有给它一个大的缓冲区。你只要求系统最多读取那么多。我告诉它最多读取
32767
,但要读取的实际数据小于
32767
。它大约
10000
但是它没有完全读取它,它被切断了。当我读取2000年前后的数据时,它会工作。我已经运行了几个测试,并确认这不是实际的TCP服务器问题。它只是在Python中导致它的行为如此怪异。
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]))