简短说明:
客户端通过TCP套接字发送服务器数据。数据长度不一,字符串由分隔符“~~~ * ~~~”
分解在大多数情况下,它工作正常。一阵子。几分钟后,数据遍布整个地方。所以我开始跟踪问题,数据最终在错误的地方,因为还没有通过。
所有内容都进入服务器脚本,并由不同的分隔符 -New Data- *解析,然后放入队列中。这是代码:
是的我知道缓冲区大小很大。不,我不会一次性发送那种大小的数据,但我一直在玩它。
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():它通过另一个分隔符解析数据“~~~ * ~~~”
所以这有效一段时间了。我正在发送的数据类型的一个示例:
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
但事情开始破裂。所以我拿了一些控制数据并将其发送到循环中。会工作一段时间然后结果开始在错误的地方结束。这出现在我的队列中:
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不能确保发送所有内容,可能会在服务器端进行某种定时器/检查,以确保不会再发生任何事情。
答案 0 :(得分:3)
基本问题是你的:
data = self.request.recv(163840000)
行不保证一次接收所有数据(无论你制作缓冲区有多大)。
为了正常运行,您必须处理一次无法获取所有数据的情况(您需要跟踪您的位置并附加到其中)。请参阅Python docs on using a socket中的相关示例:
现在我们来到套接字的主要障碍 - 发送和recv在网络缓冲区上运行。它们不一定处理你所处理的所有字节(或期望它们),因为它们主要关注的是处理网络缓冲区。通常,它们在关联的网络缓冲区已填充(发送)或清空(recv)时返回。然后他们告诉你他们处理了多少字节。在您的信息完全处理完毕之前,您有责任再次致电他们。
答案 1 :(得分: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连接之前关闭套接字
sock.sendall(command)
sock.shutdown(request.SHUT_RDWR)
sock.close()