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套接字正在从服务器接收不一致的消息_Python_Sockets_Networking_Tcp_Client - Fatal编程技术网

Python套接字正在从服务器接收不一致的消息

Python套接字正在从服务器接收不一致的消息,python,sockets,networking,tcp,client,Python,Sockets,Networking,Tcp,Client,因此,我对网络非常陌生,我使用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')

因此,我对网络非常陌生,我使用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')
        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建立到服务器的原始连接时,我只得到了正确的形式,而没有得到拆分。所以我想一定有什么事情在分裂信息。或者是腻子在做什么来确保正确组装

我需要的是变量
data
始终包含正确的行。你知道如何做到这一点吗?

编辑:
socket.recv()
正在阻塞,就像其他人所说的那样,每次调用该方法时都不会得到准确的一行。因此,套接字正在等待数据,得到它能得到的,然后返回。打印时,由于pythons默认的end参数,您可能会得到比预期更多的换行符。因此,要从服务器获取原始数据,请使用以下命令:

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

最好将套接字视为一个连续的数据流,它可能以点滴或洪水的形式到达

特别是,接收者的任务是将数据分解为它应该包含的“记录”,套接字不知道如何神奇地为您执行此操作。这里的记录是行,因此您必须读取数据并自己拆分成行

您不能保证一个
recv
将是一个完整的行。它可以是:

  • 只是一条线的一部分
  • 或几行
  • 或者,很可能是几行和另一部分行
尝试以下方式:(未经测试)


修复代码的最简单方法是打印接收到的数据而不添加新行,默认情况下,
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问题。如果要逐行处理数据,则需要对传入的数据进行自己的缓冲,并在收到新行或套接字关闭时处理该行。

tcp和套接字会发生这种情况。理论上,它可以一次到达一个字节。你的代码需要重新缝合。至于实现这一点的方法,您可以将头合并到数据包中。如果将前2或4个字节设为数据的长度,则重新组合应该很简单。请参阅此处的答案,以了解发生这种情况的更详细说明:与此答案相反,
socket.recv
是阻塞的,除非套接字已显式设置为非阻塞,或已关闭,或存在信号中断。此外,此答案不涉及收到的部分行。错误。a) 默认情况下,
socket.recv
处于阻塞状态,b)
socket.recv
在连接关闭时返回空字符串。c) 空字符串是空的。@donkopotamus Right。它被阻塞了,我将删除它。但是,如果它是非阻塞的,我的回答确实解释了为什么会有部分行。@mhawke我说的是,如果你用print函数打印一个空字符串,你得到的是一个换行符,而不是你想要的“nothing”expected@TisteAndii:你已经纠正了我的反对意见,但是你添加了一个无限循环作为一个新问题。这是不必要的复杂。只需在原始程序中将end参数设置为空字符串,就可以了。再看看endswith的论点;您缺少了一个字符…这完全取决于您可能希望如何处理此数据。。。如果你不只是打印它,而是想把它存储起来进行分析,或者通过正则表达式提取信息,那么你就需要整理完整的行。对……我想问题的最后一行会让事情变得混乱……但是从他以前的陈述和代码来看,我想他只想打印回答。即使他想保存行,使用一个列表也会更有效率,因为append()的成本是分摊的,收集块并最终在列表上调用join()。字符串连接,特别是当你可以得到一个大的响应时,效率会非常低。这是我所需要的最好的解决方案!这是因为我需要将其插入数据库,这是最好的解决方案。这非常适合打印,但我确实需要将其耦合。我现在在想,我将只记录它,并从这一点上完成它。然后处理日志文件。
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='')