2016-05-26 18 views
0

私はクライアントとして動作し、LakeShore336温度コントローラ(サーバーとして動作しています)から温度の読み取り値を取得するTCP pythonスクリプトを作成しています。私は、クライアントからサーバーにコマンドを渡し、応答を出力する必要があります。コマンドが送信された後に出力が 'Spot 2'になりますが、s.recvが呼び出されたときにハングしています。 (Pythonの2.7)TCPサーバーの応答

Client.py

import socket 

ip = '192.168.62.233' 
port = 7777    # The same port as used by the server/machine 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect((ip, port)) 

print 'Spot 1' 
s.send('KRDG? A[term]') 
print 'Spot 2' 
data = s.recv(4096) 
print 'Spot 3' 
s.close() 
print 'Received', repr(data) 

EDIT:最後に 私はちょうどので、ターミネータがあったことを

s.send('KRDG? A\r\n') 

追加する必要がありました。助けてくれてありがとう

+0

正しく、 'recv()'はブロッキング呼び出しです。サーバーが4096バイトまでの応答を送信するか、接続を閉じるまでブロックされます(それはそれよりも複雑ですが、それは単純な話です)。私はあなたが応答を送った後、サーバー上の接続を閉じるつもりはないと確信しています。 – grochmal

答えて

1

あなたのコードが「スタック」しているのは、recv()がブロック呼び出しであるからです。あなたのプロセスは着信TCPパケットを待っていて、4096バイトのバッファを割り当てています(つまり、そのバイト数まで処理できます)。

パケットが受信されると、コードが処理され、接続が閉じられ、データが印刷されます。

0

メッセージターミネータを送信する代わりに、リテラル文字列[term]を送信しています。プロトコルのドキュメントでは、文字列 "[term]"をメッセージターミネータとして使用していますが、文字列 "[term]"は意味しません。

メッセージを送信していないので(メッセージがメッセージターミネータで終了するため、メッセージターミネータで終了しないものはメッセージではないため)、デバイスはメッセージで返信しません。あなたは返信を待つので、あなたは永遠に待つでしょう。

サポートされているメッセージターミネータのリストについては、protocol specificationのセクション6.3.4.1を参照してください。キャリッジリターンに続けて改行が必要です。

コードも壊れています。 TCP recv関数を呼び出すと、メッセージを受け取ることを期待しています。しかし、それは単なるTCP機能であり、このデバイスと通信するためにどのようなメッセージプロトコルを使用しているのかわからないので、メッセージが何であるかは分かりません。送信コードが実際にメッセージを送信したことを確認するのと同じように、メッセージを受信するには独自の受信機能を作成する必要があります。

このデバイスのメッセージプロトコルは、回線の共通の概念に完全に対応しているため、回線を送受信する機能を使用すると、はるかに簡単になります。 「回線を送る」機能を使用し、「KRDG?A」を送信するように指示するだけです。次に、 "受信ライン"機能を使用してデバイスの応答を取得します。

+0

はい私はあなたが[用語]について何を意味するかを確認しました。 s.send( 'KRDG?ACR 0DHALF 0AH') ターミネーターを含めることができます。これを達成する必要がある回線機能を受信して​​いませんか?または、これらを明示的に記述してrecv()を削除する必要がありますか? –

+0

@ScottMacdonaldそれはあなた次第です。一つの方法は、 'readline'と呼べるオブジェクトを与えるために、ソケット上で' makefile() 'を呼び出すことです。 –

関連する問題