2016-10-04 52 views
0

我需要使用python將字符串發送到localhost上的特定端口。正在模擬Python中socat的功能

我可以通過使用像這樣的命令行上socat實現這一目標:

cat <text file containing string to send> | socat stdin tcp-connect:127.0.0.1:55559 

我不想作爲一個子命令運行socat命令,所以我想知道如何得到這個工作使用python模塊。

我嘗試使用套接字失敗。下面是我正在使用的腳本,它沒有達到預期的效果。

import socket 
    HOST, PORT = "127.0.0.1", 55559 
    jsonString = '{"name":"VideoStreamStatus","parameters":{"name":"video_0_0"}}' 

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

    try: 
     # Connect to server and send data 
     print "Attempting connection" 
     sock.connect((HOST, PORT)) 
     print "Sending json string" 
     sock.sendall(jsonString) 
     print "String sent" 

    finally: 
     sock.close() 

    print "Sent:  {}".format(jsonString) 

python腳本執行時沒有任何錯誤,但對正在接收socat數據的進程沒有任何影響。下面的Python腳本輸出:

Attempting connection 
    Sending json string 
    Sent:  {"name":"VideoStreamStatus","parameters":{"name":"video_0_0"}} 

有什麼,我在插座腳本做錯了還是有不同的方法,我可以在Python中使用?我會很感激任何建議。謝謝。

編輯:我試圖發送字符串的服務器是C++程序的一部分,它使用boost asio acceptor來偵聽特定地址和端口上的tcp連接。

+0

您的代碼對我來說非常適合。我的服務器'nc -l 55559',在其stdout上顯示json字符串。請描述您使用的服務器,以及是什麼讓您認爲「*對接收社區數據的流程沒有任何影響」。 –

+0

@Robᵩ我試圖發送字符串的服務器是使用boost asio acceptor偵聽特定地址和端口上的tcp連接的C++程序的一部分。 – BlooMeth

回答

0

原來是很簡單的東西。我使用socat(服務器正在接收和處理成功)發送的字符串在結尾處有換行符。我通過python套接字發送的字符串沒有新行。在python腳本的末尾添加新行後,服務器會按預期收到該字符串。

我才意識到,有一個接一個換行符,而不是運行一個Python腳本,服務器監聽在不同的端口和發送使用這兩種方法後的字符串其他。

0

根據the socat man page

當一個信道已達到EOF時,關閉其他信道的寫部分。然後,socat在終止前等待timeout秒。默認值是0.5秒。

也許你需要0.5秒,延遲你的親密,就像這樣:

finally: 
    #sock.close() 
    sock.shutdown(socket.SHUT_WR) 
    time.sleep(0.5) 
    sock.close() 

或者,也許你需要吸收服務器的關機消息,像這樣:

finally: 
    #sock.close() 
    sock.shutdown(socket.SHUT_WR) 
    sock.recv(999999) 
    sock.close() 
+0

對結果沒有任何影響。不管怎麼說,還是要謝謝你。 – BlooMeth

0

你寫入套接字後,不應立即關閉套接字:關閉可能會吞下未發送的數據。

正確的工作流程是所謂的graceful shutdown

  • 想要關閉連接部分採用了關機寫在插座上,並保持閱讀
  • 另一部分檢測到0字節從被認爲是文件結尾的套接字讀取。它關閉其插座
  • 發起者檢測到0字節讀,可以安全地關閉套接字

所以finally部分變爲:

finally: 
    try: 
    sock.shutdown(socket.SHUT_WR) 
    while True: 
     dummy = sock.recv(1024) 
     if len(dummy) == 0: break 
    finally: 
    sock.close() 
+0

感謝您的建議,但使這些更改沒有改變結果,服務器似乎仍然沒有收到任何消息。 – BlooMeth