2011-02-24 9 views
5

私はPythonのソケットに少し問題があります。誰かが接続するたびに正常に動作しますが、接続を切断するとサーバープログラムが終了します。私は、クライアントが終了した後もサーバプログラムを開いたままにしておきたい。 whileループを使用して接続を維持しますが、クライアントが接続を閉じると、サーバーは接続を閉じます。ここでPythonソケット - ソケットを有効に保つ?

は、クライアントである:ここでは

import socket, sys 
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
host = sys.argv[1] 
port = int(sys.argv[2]) 
conn.connect((host, port)) 

print("Connected to host " + sys.argv[1]) 
td = 1 
while td == 1: 
    msg = raw_input('MSG: ') 

はサーバです:

import socket, sys 

socket.setdefaulttimeout(150) 
host = ''    
port = 50005 
socksize = 1024 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind((host, port)) 
print("Server started on port: %s" % port) 
s.listen(1) 
print("Now listening...\n") 
conn, addr = s.accept() 

while True: 
    print 'New connection from %s:%d' % (addr[0], addr[1]) 
    data = conn.recv(socksize) 
    if not data: 
     break 
    elif data == 'killsrv': 
     conn.close() 
     sys.exit() 
    else: 
     print(data) 
+1

n個の接続にn + 1ソケットを使用していますか?常に聞いているソケットが1つ必要です。このリッスンソケットは、新しい接続を受け付け、接続が要求されるたびに別のソケットを開きます。 – Penang

+0

問題を示す短いコードを投稿できますか? – SimonJ

+0

n + 1個のソケット?私がフォローしているかわからないあなたはもう少し説明できますか? – AustinM

答えて

4

をクライアントが接続を閉じた場合、あなたはそれがソケットをクローズします。

ここで私が詳しく説明しようとしている切断のビットがあるようです。ソケットを作成してバインドして聴くと、他の人があなたに接続して接続するためのオープンドアを確立しました。

クライアントがあなたに接続し、accept()呼び出しを使用して接続を受け入れ、新しいソケット(conn)を取得します。このソケットは、クライアントと対話するために返されます。オリジナルのリッスンソケットはまだ存在し、アクティブですが、それを使用してさらに新しい接続を受け入れることができます。

あなたのコードを見てみると、あなたはおそらくこのような何かやりたい:

while True: 
    print("Now listening...\n") 
    conn, addr = s.accept() 

    print 'New connection from %s:%d' % (addr[0], addr[1]) 
    data = conn.recv(socksize) 
    if not data: 
     break 
    elif data == 'killsrv': 
     conn.close() 
     sys.exit() 
    else: 
     print(data) 

を、これは単なる出発点であることに注意して、他の人が示唆しているとして、あなたは、おそらくオフフォークと一緒にselect()を使用したいしてくださいプロセスまたはスレッドを生成して各クライアントにサービスを提供します。

+0

ありがとうこれは動作しているようだが、別の問題が発生します。メッセージを送信し続けると、クライアントは最終的にはフリーズします。理由は分かりません。 – AustinM

+0

クライアントコードとそのデータの送信方法を拡張できますか? – Jeff

2

あなたのコードは、単一の接続のみを受け入れている - ループのみとすぐに最初の受け付けられた接続を扱って終了しますそれは失われた。これはあなたのサーバーが存在する方法です:

data = conn.recv(socksize) 
if not data: 
    break 

あなたがする必要があることは、それ自身のループ内のそれぞれのものを処理しながら、いくつかの接続を受け入れることです。ソケットごとに実際のループである必要はないことに注意してください。selectベースのアプローチを使用して、どのソケットにイベントが関連付けられているか(データの利用可能性、接続が失われたかなど)を照会してから、すべて同じループ内にあります。

また、マルチスレッド/マルチプロセスアプローチを使用して、独自のスレッドまたはプロセス内の各クライアントを扱うこともできます。遊びの際にスケーリングの問題にぶつからないでしょう。

を参照してください:

http://docs.python.org/library/select.html

http://docs.python.org/library/multiprocessing.html

+1

ありがとうございます。万が一、selectをソケットで使用する方法の例を少し教えてください。 – AustinM

+0

@AustinM私はこれを –