所以我对网络很陌生,我使用Python Socket库连接到正在传输位置数据流的服务器。
以下是使用的代码。
SELECT GROUP_CONCAT(tc.`name` ORDER BY tc.entity_id) AS cat_ids
FROM products AS tp
JOIN categories AS tc
ON FIND_IN_SET(tc.entity_id, tp.category_ids)
GROUP BY tp.category_ids;
问题是数据以不一致的形式到达。
大部分时间它都以正确的形式到达:
import socket
BUFFER_SIZE = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((gump.gatech.edu, 756))
try:
while (1):
data = s.recv(BUFFER_SIZE).decode('utf-8')
print(data)
except KeyboardInterrupt:
s.close()
其他时候它可以分成两行,如下所示:
2016-01-21 22:40:07,441,-84.404153,33.778685,5,3
有趣的是,当我使用Putty建立与服务器的原始连接时,我只能得到正确的表单,而不是拆分。所以我想,必然会发生一些分裂信息的事情。或Putty正在做的事情总是正确地组装它。
我需要的是变量2016-01-21
22:40:07,404,-84.396004,33.778085,0,0
始终包含正确的行。知道怎么做到这一点吗?
答案 0 :(得分:1)
最好将套接字视为连续的数据流,这些数据可能会出现在点滴或单调或洪水中。
特别是,接收器的工作是将数据分解为它应该包含的“记录”,套接字并不会神奇地知道如何为您执行此操作。这里的记录是行,因此您必须自己读取数据并分成行。
您不能保证单个recv
将是一个完整的整行。它可能是:
尝试类似:(未经测试)
# we'll use this to collate partial data
data = ""
while 1:
# receive the next batch of data
data += s.recv(BUFFER_SIZE).decode('utf-8')
# split the data into lines
lines = data.splitlines(keepends=True)
# the last of these may be a part line
full_lines, last_line = lines[:-1], lines[-1]
# print (or do something else!) with the full lines
for l in full_lines:
print(l, end="")
# was the last line received a full line, or just half a line?
if last_line.endswith("\n"):
# print it (or do something else!)
print(last_line, end="")
# and reset our partial data to nothing
data = ""
else:
# reset our partial data to this part line
data = last_line
答案 1 :(得分:1)
修复代码的最简单方法是打印收到的数据,而不用添加新行,print
语句(Python 2)和print()
函数( Python 3)默认做。像这样:
Python 2:
print data,
Python 3:
print(data, end='')
现在print
不会在每个打印值的末尾添加自己的新行字符,只会打印接收数据中的新行。结果是每行打印而不根据每个`socket.recv()接收的数据量进行拆分。例如:
from __future__ import print_function
import socket
s = socket.socket()
s.connect(('gump.gatech.edu', 756))
while True:
data = s.recv(3).decode('utf8')
if not data:
break # socket closed, all data read
print(data, end='')
这里我使用了一个非常小的缓冲区大小3,这有助于突出问题。
请注意,这仅解决了打印数据的POV问题。如果您想逐行处理数据,那么您需要自己缓冲传入的数据,并在收到新行或关闭套接字时处理该行。
答案 2 :(得分:-2)
修改强>:
socket.recv()
正在阻塞,就像其他人所说的那样,每次调用方法时都不会得到确切的行。因此,套接字正在等待数据,获取它可以获得的内容然后返回。打印时,由于pythons默认结束参数,您可能会获得比预期更多的换行符。因此,要从服务器获取原始内容,请使用:
import socket
BUFFER_SIZE = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('gump.gatech.edu', 756))
try:
while (1):
data=s.recv(BUFFER_SIZE).decode('utf-8')
if not data: break
print(data, end="")
except KeyboardInterrupt:
s.close()