2013-11-26 34 views
0
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驅動程序上。python tcp put connection reset

這種方法可以看出,爲被推出的每一行數據調用netcat工具。

問題: 1.)有沒有更好的方式來完成這項任務,無需每次打開一個TCP連接,我想推送的每一行數據?我每分鐘都會運行一次,這導致了大量TIME_WAIT狀態的連接。

2.)我可以用一個持久的TCP套接字每次推1000條線嗎?我已經查看了python中的netcat實現,但是當我推送所有行時,它們似乎會導致連接重置

例如: 當我嘗試使用下面的方法時,我不斷收到錯誤:error (104「由對等連接復位」)數據的

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' 
+0

是的每條線都在他們的新線上開始。所以第二種方法適用於多達20行,然後我從opentsdb驅動程序獲得連接重置。 –

+0

好的,請(a)向我們展示一些示例數據,這樣人們就不必猜測它的樣子,並且(b)更新答案以解釋它在失敗之前可以使用20行左右,因爲正如它所寫的那樣意味着它根本不起作用。 – abarnert

+0

同時,如果OpenTSDB出於某種原因不喜歡在一行中獲取大量單獨的命令,那麼將它們連接在一起併發送一個大批量文件又如何呢?換句話說,當你的循環在20之後失敗時,'s.sendall('。join(data_list))'是否能夠工作100條? – abarnert

回答

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)) 
+0

是的,重要的是要放置'放' - 謝謝指出這一點。 –