LoginSignup
3
9

More than 5 years have passed since last update.

clientの再接続を試みた話

Last updated at Posted at 2017-04-15

※pythonもソケット通信もあまり詳しくない人が書いてます。
※ほかに良い方法があれば、よろしくお願いします。

ひょんなことから、サーバーとクライアント間の通信を行う必要がありました。
そこで、クライアント側は通信に失敗しても、実行終了することなく、再度接続を試み続けたい!
と思ったのですが、そこで躓きました・・・

ソケット作り直せばいいだろと思い、既にある変数にもう一度代入!じゃできなかった・・・

参考にさせていただいたプログラム[2から抜粋]

import socket

host = "xxx.xxx.xxx.xxx"
port = xxxx

client = socket.socket(socket.AF_INET, 
socket.SOCK_STREAM) #以下、socket.socketと呼ぶ

client.connect((host, port)) #以下、socket.connect と呼ぶ
client.send("from nadechin")

問題

実際にはwhileで回すことが多いんじゃないかと思いますが、サーバーが落ちた時、以下のようなことができない。

client = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
client.connect((host, port))
client.send("from nadechin")

=====ここでサーバーが落ちる=====
client = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
client.connect((host, port))
client.send("from nadechin")

ここで、socket.socketをなくした場合やclose, shutdown, timeoutといったsocketの他のメソッドを使っても、うまくいかなかった。

解決策(?)

当たり前ですけど、一度クライアントを落としてしまえばうまくいきました。
ということで、既に作られたsocketが破棄されれば良いんだなと思い、以下のようなクラスを作ることでこの対策をしました。
(簡単のため、エラー処理は省略-try:)

class client(object):
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #try:
        self.client.connect((self.host, self.port))

    def send(self):
        #try:
        self.client.send("ok")

    def execute(self):
        while 1:
            self.__init__(self.host, self.port)
            self.send()

client(host, port).execute()

以上のように書くと、うまくいきました。

下記ではうまくいかなかったのが不思議でした。なぜ・・・

class client(object):
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #try:
        self.client.connect((self.host, self.port))

    def send(self):
        #try:
        self.client.send("ok")

while 1:
    client(host, port).execute()

他につまずいたこと

・python実行時、ついローカルネットワークにしてしまった
設定されてしまったので、ファイアウォールの設定を見直す羽目に

サーバー・クライアント作成時に参考にしたページ:

[1]マルチスレッドサーバー
http://stackoverflow.com/questions/23828264/how-to-make-a-simple-multithreaded-socket-server-in-python-that-remembers-client
[2]クライアント
http://qiita.com/nadechin/items/28fc8970d93dbf16e81b
[3]エラー
https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx

大変参考になりました。ありがとうございました。
エラー対策はstack overflowさんで探しても、あまり良いものはありませんでした。
一応、筆者はerror 10053, 10054(一応,10056,10057も)を上記で記述した方法でやっています。
それ以外のエラーはsocket.connectをcontinueで続けています。
※url,勝手に張ってはいけない等のことありましたら、よろしくお願いします。

実装はこちら?(多分あってます)
https://github.com/jackee777/server_and_client/tree/master/simple_server

3
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
9