pythontcp套接字数据有时缺少部分。套接字溢出?

2024-04-19 16:57:40 发布

您现在位置:Python中文网/ 问答频道 /正文

简要说明:

客户端通过TCP套接字发送服务器数据。数据长度不同,由分隔符“~~~*~~~”分隔

在大多数情况下,它工作得很好。一段时间。几分钟后,数据就到处都是。所以我开始跟踪问题,结果数据放错地方了,因为完整的东西还没有通过。在

所有内容都进入服务器脚本,并由不同的分隔符-NewData-*进行解析,然后放入队列中。代码如下:

是的,我知道缓冲区很大。不,我不会一次性发送那种大小的数据,但我是在玩弄它。在

class service(SocketServer.BaseRequestHandler):
    def handle(self):
        data = 'dummy'

        #print "Client connected with ", self.client_address
        while len(data):
            data = self.request.recv(163840000)
            #print data
            BigSocketParse = []
            BigSocketParse = data.split('*-New*Data-*')

            print "Putting data in queue"
            for eachmatch in BigSocketParse:
                #print eachmatch
                q.put(str(eachmatch))

            #print data
            #self.request.send(data)

        #print "Client exited"
        self.request.close()


class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

t = ThreadedTCPServer(('',500), service)
t.serve_forever()

然后,我有一个线程在运行,而不是q.empty():它通过另一个分隔符“~~~*~~~”解析数据

所以这暂时有效。我是一个发送数据的例子:

^{pr2}$

但事情开始破裂了。所以我取了一些控制数据,循环发送。会有一段时间的效果然后结果就错了。在我的队列中出现了这个:

2016-02-23 18:01:24.140000~~~*~~~Snowboarding~~~*~~~Blue Hills~~~*~~~Powder 42
~~~*~~~Board Rental~~~*~~~15.0~~~*~~~1~~~*~~~http://bigshoes.com
~~~*~~~No Wax~~~*~~~50.00~~~*~~~No Ramps~~~*~~~2016-02-23 19:45:00.000000~~~*~

删去最后一个“~~-15”。在

所以完全相同的数据起作用,后来就不行了。这对我来说是某种溢出。在

客户端连接如下:

class Connect(object):

    def connect(self):
        host = socket.gethostname() # Get local machine name
        #host = "127.0.0.1"
        port = 500                # Reserve a port for your service.
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #print('connecting to host')
        sock.connect((host, port))
        return sock

    def send(self, command):
        sock = self.connect()
        #recv_data = ""
        #data = True

        #print('sending: ' + command)
        sock.sendall(command)
        sock.close()
        return

它不会等待回应,因为我不想让它在等待回应。但它会关闭套接字,而且(据我所知)我不需要刷新套接字缓冲区或任何它应该在连接关闭时自动清除的东西。在

非常感谢你在这方面的帮助。在这一点上我有点多余。在

更新:

我在我的本地机器和一个相当强大的服务器上运行这个程序,我会被迫相信这是硬件问题。服务器/客户机都在本地运行,套接字被用作它们通信的一种方式,所以我不认为延迟是原因。在

我一直在读有关TCP通信的问题。我觉得我很快就会失去理智,但我开始怀疑,这是否不是一个溢出,而是某种拥堵之王。在

如果客户机上的sendall不能确保所有内容都已发送,那么可能需要在服务器端进行某种计时器/检查,以确保不会再发送任何内容。在


Tags: 数据self服务器host内容datarequestdef
2条回答

如前所述,即使缓冲区大小很大,也不会收到完整的消息。你需要一直接收直到你得到零字节。您可以编写自己的生成器来获取request对象并生成部分。好的一面是,你可以在一些消息仍在进来的时候开始处理消息

def recvblocks(request):
    buf = ''
    while 1:
        newdata = request.recv(10000)
        if not newdata:
            if buf:
                yield buf
            return
        buf += newdata
        parts = buf.split('*-New*Data-*')
        buf = parts.pop()
        for part in parts:
            yield part

但你也需要对你的客户进行修复。您需要在关闭之前关闭套接字才能真正关闭TCP连接

^{pr2}$

基本问题是:

data = self.request.recv(163840000)

line不保证一次接收所有数据(不管缓冲区有多大)。在

为了正常工作,您必须处理不能一次获得所有数据的情况(您需要跟踪您所在的位置,并将其附加到数据中)。请参阅Python docs on using a socket中的相关示例:

Now we come to the major stumbling block of sockets - send and recv operate on the network buffers. They do not necessarily handle all the bytes you hand them (or expect from them), because their major focus is handling the network buffers. In general, they return when the associated network buffers have been filled (send) or emptied (recv). They then tell you how many bytes they handled. It is your responsibility to call them again until your message has been completely dealt with.

相关问题 更多 >