1

だから私は非常に単純なエコーサーバー/クライアントのような取り引きをいじっています。最終的にはゲームサーバーを作る予定ですが、今は基本的な部分をセットアップするだけです。

サーバーは次のとおりです。http://pastebin.com/qtfrMGur

クライアントは次のとおりです: http://pastebin.com/3VK3VxPX

したがって、私の問題は、クライアントが切断されると、socket.error: [Errno 10054] An existing connection was forcedly closed by the remote host. というメッセージが表示されることです。読み取り可能なソケット リストに保留中の情報がない場合、select.select() が false (または空のリストなど) を返したという印象を受けました。これがエラーの原因のようですが、クライアントが存在しない場合に select.select() が true を返すのはなぜですか (26 行目)。実際のエラーは、行 27 で情報を取得しようとしたときに発生します。ソケットのクライアント側が閉じていると仮定すると、[] を返してから、else に移動するだけではいけないので、これに本当に混乱しています。 31 行目でそのクライアントを破棄しますか?

他に何を投稿すればよいのかよくわかりません。これは非常に初歩的な問題のように思えます。通常、ツイストなどのより抽象的なライブラリを使用して簡単にしますが、このプロジェクトでは従来の BSD ソケットを使用する必要があります。他に必要な情報がある場合は、質問してください。

ありがとう。

編集:だから私は select.select(...)[0] の値を出力するためにそこに print ステートメントを入れました。

for cl in clients:
        ready = select.select([cl], [], [], .1)[0]
        print ready
        if ready:
            data = cl.recv(size)
            if data:
                print data
                #cl.send(data)
            else:
                print "Client Quit\n"
                clients.remove(cl)
                cl.shutdown(socket.SHUT_RDWR)
                cl.close()
                print len(clients)

ご覧のとおり、適切なシャットダウンも行っています。問題は、クライアントが終了すると、 select.select(...) がクライアントソケットを読み取り可能なソースとして返すため、 cl.recv が呼び出され、相手側で cl が閉じられているためエラーがスローされることです。 . 少なくともこれは私の疑いです。

それで、誰かが私がここで間違っているかもしれないことを説明してもらえますか? クライアントがラスト ダイイング メッセージを送信する理由

ありがとう

EDIT2:だから、私は自分のdebianマシンを起動しましたが、コードは問題なく動作します。これを行っているのはWindowsだけです。これはある種のバグですか?私は、ソケット ライブラリが内部のすべてのものを抽象化して、OS 間のインターフェイスを同一にするという印象を受けました。

4

1 に答える 1