Python 套接字正在从服务器接收不一致的消息
Python Socket is receiving inconsistent messages from Server
所以我对网络还很陌生,我使用 Python Socket 库连接到传输位置数据流的服务器。
这是使用的代码。
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
但有时它会像这样分成两行到达:
2016-01-21
22:40:07,404,-84.396004,33.778085,0,0
有趣的是,当我使用 Putty 建立到服务器的原始连接时,我只得到正确的形式,而没有得到拆分。所以我想一定有什么事情在分裂消息。或者 Putty 正在做的事情总是 assemble 正确。
我需要的是变量 data
始终包含正确的行。知道如何实现吗?
编辑:
socket.recv()
正在阻塞,就像其他人所说的那样,每次调用该方法时都不会得到准确的一行。因此,结果是,套接字正在等待数据,获取它可以获取的数据,然后 returns。当你打印这个时,由于 python 的默认结束参数,你可能会得到比你预期更多的换行符。因此,要从您的服务器获取原始内容,请使用:
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()
最好将套接字视为连续的数据流,它可能以点点滴滴的形式到达,也可能像洪水一样涌来。
特别是,将数据分解成它应该包含的 "records" 是接收者的工作,套接字不知道如何为你做这件事。这里记录的是行,所以你必须自己读取数据并拆分成行。
您不能保证单个 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
修复代码的最简单方法是打印接收到的数据而不用添加新行,即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 问题。如果您想处理数据 line-by-line 那么您需要对传入数据进行自己的缓冲,并在收到新行或套接字关闭时处理该行。
所以我对网络还很陌生,我使用 Python Socket 库连接到传输位置数据流的服务器。
这是使用的代码。
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
但有时它会像这样分成两行到达:
2016-01-21
22:40:07,404,-84.396004,33.778085,0,0
有趣的是,当我使用 Putty 建立到服务器的原始连接时,我只得到正确的形式,而没有得到拆分。所以我想一定有什么事情在分裂消息。或者 Putty 正在做的事情总是 assemble 正确。
我需要的是变量 data
始终包含正确的行。知道如何实现吗?
编辑:
socket.recv()
正在阻塞,就像其他人所说的那样,每次调用该方法时都不会得到准确的一行。因此,结果是,套接字正在等待数据,获取它可以获取的数据,然后 returns。当你打印这个时,由于 python 的默认结束参数,你可能会得到比你预期更多的换行符。因此,要从您的服务器获取原始内容,请使用:
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()
最好将套接字视为连续的数据流,它可能以点点滴滴的形式到达,也可能像洪水一样涌来。
特别是,将数据分解成它应该包含的 "records" 是接收者的工作,套接字不知道如何为你做这件事。这里记录的是行,所以你必须自己读取数据并拆分成行。
您不能保证单个 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
修复代码的最简单方法是打印接收到的数据而不用添加新行,即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 问题。如果您想处理数据 line-by-line 那么您需要对传入数据进行自己的缓冲,并在收到新行或套接字关闭时处理该行。