私はむしろここでnoobですが、ソケットをポーリングできるスクリプトをセットアップしようとしています。ソケットデータが送信されていないときは、ループが実行され続け、他の処理が実行されます。私はselect()を使って見つかったいくつかの例を試してきましたが、コードをどのように整理しても、server.recv()行の上または近くで停止して応答を待つようです。クライアントからデータが送信されなかった場合、またはクライアント接続が存在しない場合は、これをスキップします。Pythonソケットセレクトがハングアップしています - ソケットデータを待っている間に他のタスクを実行していますか?
このアプリケーションでは、何らかの違いがあれば、返信データを送信するためのサーバースクリプトは必要ありません。
実際のアプリケーションは、ループを実行し、いくつかのLEDをアニメーション化することです(これは、Raspberry PiのI/Oへのルートアクセスが必要です)。私はアニメーションの制御パラメータを渡すソケットを介して別の別のスクリプトからこのスクリプトデータを送信します。このようにして、外部スクリプトはルートアクセスを必要としません。
これまでデータの送受信がうまくいっていますが、受信データがないと回転を続けることができません。これはselect()が許そうとしていたものだと私は理解していますが、私が見つけた例はそうした方法では動作していないようです。
server.setblocking(0)をいくつか別の場所に追加しようとしました。 (私が正しく理解していれば、データが送信されていなければ、recv()をスキップするコードを非ブロックのインスタンスで許可する必要がありますが、これはオフになっている可能性があります)。私はここに例の私のコードをベースとしている
: http://ilab.cs.byu.edu/python/select/echoserver.html
ここでは、クライアント側のスクリプトに続いて、サーバー側のスクリプトです。
サーバコード:sockselectserver.py
#!/usr/bin/env python
import select
import socket
import sys
server = socket.socket()
host = socket.gethostname()
port = 20568
size = 1024
server.bind((host,port))
server.listen(5)
input = [server,sys.stdin]
running = 1
while running:
inputready,outputready,exceptready = select.select(input,[],[])
for s in inputready:
if s == server:
# handle the server socket
client, address = server.accept()
input.append(client)
elif s == sys.stdin:
# handle standard input
junk = sys.stdin.readline()
running = 0
else:
# handle all other sockets
data = s.recv(size)
if data:
s.send(data)
else:
s.close()
input.remove(s)
print "looping"
server.close()
クライアントコード:skclient.py
#!/usr/bin/python # This is client.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 20568 # Reserve a port for your service.
s.connect((host, port))
data = "123:120:230:51:210:120:55:12:35:24"
s.send(data)
print s.recv(1024)
s.close # Close the socket when done
私はこの例で達成したいことを繰り返す "ループ" を参照してくださいすることですクライアントスクリプトがデータを送信したら、そのデータの印刷を参照してから、「ループ」の繰り返し印刷を繰り返してください。それは私がそこから取ることができる意図されていることをやっていると私に伝えます。
私はクライアントを実行するたびに、これをテストすると面白いですが、 "ループ"が画面に3回印刷されているのを確認しました。私は選択内で何が起こっているか完全に理解していませんが、1回だけ印刷すると仮定します。
select.select()を別の場所に移動しようとしましたが、毎回呼び出す必要があるようでした。それ以外の場合、サーバーは応答を停止します(たとえば、無限のwhile :ループ)。
これは、メーカークラスの他のハッカータイプに教えることができるほど簡単にできると思っています。だから、私はマルチスレッドとより精巧なソリューションであまりにも夢中になる必要はないと思っています。最後の手段として、私のすべてのパラメータを外部スクリプトからmySQLに記録し、このスクリプトを使用してテーブルから戻ってクエリを実行することを検討しています。私はそこに経験があり、おそらく動作するだろうが、このソケット角度はより直接的な解決策になると思われる。
ご協力いただきありがとうございます。
サーバーは独自のループでなければなりません。imo – YOU
クイック返信ありがとうございます。私はこれをどのように実装するのか分かりません。サンプルコードを共有することはできますか?私はループ内のすべてをラップしますか?もしそうなら、私は他の関数(クライアントが着信データを送信するときにのみ中断される何度も呼び出される関数)をどこで呼び出すでしょうか? – kjav
'select.select(input、[]、[]、1)'オプションで 'select.select()'をタイムアウト(秒)オプションで呼び出してみてください。 – acw1668