【问题标题】:python tcp put connection resetpython tcp put连接重置
【发布时间】:2013-11-26 00:55:01
【问题描述】:
def put_data(line = '', dest_host = 'server', dest_port = '876'):
    ''' This method once invoked pushes data to dest_host and dest_port  '''
    if line:
        cmd = '/bin/echo put ' + line + '| ' + '/bin/nc -w 15 server port'
        print('TCP put using command: ' + cmd)
        os.system(cmd)

我正在使用上述方法将数据行 TCP 放入 HBASE 之上的 opentsdb 驱动程序。

可以看出,此方法为每行推出的数据调用 netcat 实用程序。

问题: 1.)有没有更好的方法来完成这项任务,不必每次都为我想要推送的每一行数据打开一个 TCP 连接?我每分钟运行一次,这导致大量连接处于 TIME_WAIT 状态。

2.) 我可以使用持久 TCP 套接字一次推送 1000 行吗?我已经查看了 python 中的 netcat 实现,但是当我推送所有行时,它们似乎会导致对等方的连接重置

例如: 当我尝试使用以下方法时,我不断收到错误消息:error(104, 'Connection reset by peer')

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(server, port)
for line in data_list:
    s.sendall(line)
s.close()

error(104, 'Connection reset by peer')

正在推送的数据示例行:

line1 = 'fin.wait2 1385428269 0.0 host=srv1 testname=tcp source=nag03 product=rebuild'
line2 = 'established 1385428269 11.0 host=srv2 testname=tcp source=nag03 product=rebuild'
line3 = 'fin.wait1 1385428269 0.0 host=srv3 testname=tcp source=nag03 product=rebuild'
line4 = 'last.ack 1385428269 0.0 host=srv4 testname=tcp source=nag03 product=rebuild'
line5 = 'unknown 1385428269 0.0 host=srv5 testname=tcp source=nag03 product=rebuild'
line6 = 'syn.recv 1385428269 0.0 host=srv6 testname=tcp source=nag03 product=rebuild'

【问题讨论】:

  • 是的,每一行都从它们的新行开始。所以第二种方法适用于最多 20 行,然后我从 opentsdb 驱动程序获得连接重置。
  • 好的,请 (a) 向我们展示一些示例数据,这样人们就不必猜测它的样子,并且 (b) 更新答案以说明它适用于 20 行左右在失败之前,因为正如所写的那样,它意味着它根本不起作用。
  • 同时,如果 OpenTSDB 出于某种原因不喜欢连续获取一大堆单独的命令,那么将它们连接在一起并发送一大批呢?换句话说,当您的循环在 20 之后失败时,s.sendall(''.join(data_list)) 是否适用于整整 100 行?
  • 嗯 - 我在每行之后添加了一个明确的 '\n' 似乎正在工作......非常感谢。由于您的建议/答案在 cmets 中,我无法接受
  • 好的,我写了它作为答案,有更多细节。

标签: python tcp


【解决方案1】:

问题是你的行末尾没有换行符。

您的基于 netcat 的代码正在使用 echo 将行传递给 netcat,它不带任何参数,会在末尾添加一个换行符,因此它可以工作。

但是您的基于 Python socket 的代码没有添加任何换行符。

所以,你想向它发送五个这样的命令:

put fin.wait2 1385428269 0.0 host=srv1 testname=tcp source=nag03 product=rebuild
put established 1385428269 11.0 host=srv2 testname=tcp source=nag03 product=rebuild
put fin.wait1 1385428269 0.0 host=srv3 testname=tcp source=nag03 product=rebuild
put last.ack 1385428269 0.0 host=srv4 testname=tcp source=nag03 product=rebuild
put unknown 1385428269 0.0 host=srv5 testname=tcp source=nag03 product=rebuild
put syn.recv 1385428269 0.0 host=srv6 testname=tcp source=nag03 product=rebuild

……但相反,你发送的是这样一大行:

put fin.wait2 1385428269 0.0 host=srv1 testname=tcp source=nag03 product=rebuildput established 1385428269 11.0 host=srv2 testname=tcp source=nag03 product=rebuildput fin.wait1 1385428269 0.0 host=srv3 testname=tcp source=nag03 product=rebuildput last.ack 1385428269 0.0 host=srv4 testname=tcp source=nag03 product=rebuildput unknown 1385428269 0.0 host=srv5 testname=tcp source=nag03 product=rebuildput syn.recv 1385428269 0.0 host=srv6 testname=tcp source=nag03 product=rebuild

要么它被你的数据弄糊涂并挂断,要么拒绝你过长的线路作为 DoS 尝试,要么只是等待应该结束线路的换行符并且永远不会得到它并最终超时。

无论根本问题是什么,根本原因是缺少换行符,解决方法是将它们放在那里。

当我们这样做时,您的 netcat 代码会在每个命令的开头附加一个 put,而您的 socket 代码不会,您可能还需要修复它。所以:

for line in data_list:
    s.sendall('put {}\n'.format(line))

【讨论】:

  • 是的,放置“put”也很重要——也感谢您指出这一点。
猜你喜欢
  • 1970-01-01
  • 2012-08-02
  • 1970-01-01
  • 2017-08-05
  • 1970-01-01
  • 2013-09-04
  • 2019-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多