0

Python で小さなチャット サーバーとクライアントのペアを実装しようとしています。サーバーとクライアントの両方を既に作成しましたが、Web サイトでサーバーを実行しようとすると少し問題が発生します。

この例はドキュメントからのものです。複数のクライアントをサポートするために少し変更しました。

#!/usr/bin/env python

import socket

TCP_IP = '127.0.0.1'
TCP_PORT = 9090
BUFFER_SIZE = 256

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)

while True:
    conn, addr = s.accept()
    print('Connection address:', addr)
    while True:
        data = conn.recv(BUFFER_SIZE)
        if not data: continue
        # handle the request 
    conn.close()

このサーバーは while ループを使用します。つまり、一度だけ実行する必要があります。ただし、サーバーを 1 回だけ実行する方法がわかりません。

複数のクライアントを操作するためにループ内でsocket.accept()実行する必要があることは理解していますが、問題は実際に Web サーバーで実行していて、接続を永久に待機させていることです。while

助けて!〜チャンス

4

4 に答える 4

1

1 つには、サーバーは複数のクライアントを処理しますが、一度に 1 つだけです。これは、リクエスト/レスポンス ベースのサーバー (HTTP サーバーなど) ではそれほど問題ではありません。あなたの場合、おそらく各クライアントへのオープンな接続を維持したいと思うでしょう。

SocketServerライブラリを確認してください。このライブラリは、複数のクライアントを同時に処理するサーバーを作成するのに役立ちます。これには、ThreadingMixin を使用できます。

このライブラリに提供されている例は、チャット サーバーに非常によく似ているため、独自のコードの基礎として使用できます。

サーバーでは、接続されているクライアントのリストを作成する必要があります。無限ループでクライアントから受信データを読み取る RequestHandler を作成する必要があります。クライアントからデータを受信すると、リスト内の他のすべてのクライアントにデータを送信する必要があります。

于 2012-09-15T19:22:33.030 に答える
1

注: これは、後続のコメントではなく、最初のコード サンプルを指します。

そのため、このコード サンプルをどのドキュメントから取得したかはわかりません。それへのリンクを含めることができれば、それは素晴らしいことです。

この行を変更する必要があるかもしれないと思います:

if not data: continue

これに:

if not data: break

私が覚えていることから、「続行」は残りのステートメントの実行を破棄し、すぐにループの先頭に戻りますが、「ブレーク」はループの最後に移動します。これにより、残りのロジックを閉じることができます。その仕事をするための接続。

私が収集できることから、これは1つの接続を許可し、その後の接続試行では何もしないようです. これが「永遠に走る」という意味だと思います。実行中ですが、後続のリクエストに応答していないようです。

于 2012-09-16T02:23:14.910 に答える
0

複数のクライアントの問題を修正するには:

#!/usr/bin/env python

import threading
import socket

clients = {}

class ClientThread(threading.Thread):
    def __init__(self, conn, addr):
        threading.Thread.__init__(self)
        self.conn = conn
        self.addr = addr
        print("Connected to", str(self))
    def __str__(self):
        return "{0}:{1}".format(*self.addr)
    def run(self):
        while True:
            try:
                data = self.conn.recv(256)
            except socket.error:
                print("Disconnected from", str(self))
                break
            if not data: continue
            k = str(data, "UTF-8")
            print(k)
            if k.startswith("LOGN"):
                name = k.split()[1]
                clients[name] = self
                self.conn.send(bytes("[SVR] Logged in as @" + name + "\n", "UTF-8"))
            elif k == "QUIT": break
        conn.close()

TCP_IP = '127.0.0.1'
TCP_PORT = 9090
BUFFER_SIZE = 256

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
while True:
    conn, addr = s.accept()
    ClientThread(conn, addr).start()

しかし、私はまだ私のウェブサイトでそれを実行する方法を理解することができません。

于 2012-09-15T20:38:42.820 に答える
0

簡単な問題。1) ネストされた while ループには終わりがありません。したがって、1 つのクライアントからのみデータを受け取ります。2) おそらく、新しい接続ごとに個別のスレッドが必要です。何かのようなもの:

While True:
    if new_connection:
        launch_new_thread_for_it

3) クライアントが切断されたときの状況を忘れずに発見してください! クライアントがいなくなった場合、新しいデータがあるかどうかを確認しても意味がありません。

于 2012-09-15T19:24:13.873 に答える