2017-06-06 24 views
0

私は、Pythonでソケットモジュールを使って簡単なチャットシステムを作ろうとしました。私はサーバーをシャットダウンする必要があるたびにプロセスを終了する必要があることを除いて、すべてが機能します。そして私は毎回これをやりたいとは思わない。 私の質問は次のとおりです:Pythonソケット - サーバーをシャットダウンする方法

サーバ端末にと入力してシャットダウンすると、どのように機能するのですか?

私はすでにこれを行うことを試みた:

def close(self): server.close(self) server.shutdown(self)

をしかし、それは動作しません。私がclose()をタイプすると何も起こりません。何もない。

Heresサーバー全体のコード: https://pastebin.com/gA4QYmQe すべてのヘルプが役に立ちます。ありがとう。

+0

もっとコードを追加するように投稿を修正してください。このコードスニペットの "server"インスタンスとは何ですか?あなたのサーバープログラムの全体的な構造は何ですか? 「シャットダウン」とはどういう意味ですか?プログラムを終了しますか?新しい接続を聞くのをやめますか?既存の接続をすべて閉じて、サーバープログラムを実行したままにしますか? – Hannu

+0

最初の投稿を編集しました。それはサーバー全体をシャットダウンする必要があります(プログラムを閉じます) – smaxxx

+0

あなたが興味を持っている場合のためだけに別のコメント。これは現在、1つの同時接続のみを受け入れ、クライアントが接続をシャットダウンするとうまく回復しません。通常は、メインプログラムがaccept()で待機し、新しい接続が確立されると、ソケットとアドレスをパラメータとしてスレッドを起動し、メインプログラムがaccept()に戻る間にスレッドが個々の接続を処理します。すぐに。クライアントが接続を閉じると、それを処理するスレッドは終了し、他のクライアント接続とメインループはそのまま残します。 – Hannu

答えて

0

あなたの近く()関数がありうーん...そこコード(あなたの「MY IP」と「SERVERIP」おそらくあなたが望んでいないしているものには多くの問題がありますが、これはポイントの横にあります。 "self"パラメータ。これはクラスではないので無意味です。try-except-structureから呼び出す場合は、close関数をコードの先頭に移動する必要があります。最初の[閉じる()、およびシャットダウンは、私がこれを行うには、あなたの近くに()を修正した。引数を取り、それが動作します。

def close(): 
    server.shutdown(socket.SHUT_RDWR) 
    server.close() 
    print ("closed") 

あなたのソケットを開くと、あなたはまたにSO_REUSEADDRを設定する必要があります(

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 

をしかし、どのように正確に、あなたは近くに呼び出している:(あなたがそれをシャットダウンする場合は、サーバを再起動することができることを意味し、代わりのサーバーポートで終了するTIME_WAIT状態のための分を待っている)のアドレスを再利用可能にします)どこかで "シャットダウン"とタイプすると?あなたはこれをやっていません。プログラムはソケットループ内にあり、キーボード入力を読み取っていません。

私はこのプログラムにキーボード入力を加えても何のポイントも見ません。まず、ブロック入力(ソケット入力とキーボード入力)が2つあり、これを管理する必要があります。可能ですが、間違いなく複雑です。次に、「シャットダウン」と入力してEnterキーを押すのではなく、Ctrl + Cを押す方が速いです。

現在、キーボード割り込み後にクローズを呼び出すことはありません。これを内部のKeyboardInterruptに追加しました(あなたが外に出すことができます - 何もしていないし、決して到達していません)、あなたのプログラムをすっきりシャットダウンし、すべての接続を閉じます。試してみる前に、前にコードの底から近い()関数を移動することを忘れないでください:文:

except KeyboardInterrupt: 
     print("[!] Keyboard Interrupted!") 
     close() 
     break 

リモートシャットダウンをしたい場合は(あなたがソケットに「シャットダウン」と入力した場合、サーバーがシャットダウンします)、これをサーバループに追加することができます:

if message == "shutdown": 
    close() 
    exit(0) 

その他の問題もあります。たとえば、サーバーを起動し、サーバーに接続して接続をシャットダウンすると、サーバーはlisten()に戻らないため、サーバーは終了します。

これは(私の意見では)多少悪いプログラミングであり、グローバル変数として "server"を使用するとそうです。私はむしろクラスを作成し、すべてのソケット操作をそれに入れますが、スタイルが重要でない場合は、これが機能するはずです。

ハヌ

関連する問題