我正在尝试在Python中实现一个小型聊天服务器 - 客户端对。我已经写了我的服务器和我的客户端,但是我在尝试在我的网站上运行服务器时遇到了一些问题。
此示例来自文档。我修改了一下以支持多个客户端:
#!/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循环,这意味着它应该只运行一次。但是,我无法弄清楚如何只运行一次服务器。
我理解我必须在socket.accept()
循环中执行while
以便与多个客户端一起工作,但问题实际上是在我的Web服务器上运行并使其等待连接永远。
救救我!可能有〜
答案 0 :(得分:1)
首先,您的服务器将处理多个客户端,但一次只能处理一个客户端。这对基于请求 - 响应的服务器(如HTTP服务器)来说并不是那么糟糕。在您的情况下,您可能希望保持与每个客户端的开放连接。
您可能需要查看SocketServer库。此库将帮助您创建将同时处理多个客户端的服务器。为此,您可以使用ThreadingMixin。
为此库提供的示例与聊天服务器非常相似,因此您可以将其用作自己代码的基础。
在服务器中,您需要创建已连接客户端的列表。您应该创建一个RequestHandlder,它将在无限循环中读取来自客户端的传入数据。在从客户端接收数据后,它应该将数据发送到列表中的所有其他客户端。
答案 1 :(得分:1)
注意:这是指初始代码示例,而不是后续评论。
因此,不确定从哪个doc中提取此代码示例。如果你可以包含一个链接,那将是伟大的。
我认为您可能需要更改此行:
if not data: continue
对此:
if not data: break
从我记得“继续”将丢弃执行剩余的语句并立即返回到循环的顶部,而“break”将带你到循环的底部,这应该允许其余的关闭连接以完成其工作的逻辑。
从我可以收集的信息来看,这将允许一个连接,然后似乎在随后的连接尝试中没有做任何事情。我认为这就是“永远奔跑”的意思。在运行中,但似乎没有响应后续请求,不是吗?
答案 2 :(得分:0)
简单的问题。 1)你的嵌套while循环没有结束。因此,您将只从一个客户端接收数据。 2)每个新连接可能需要单独的线程。类似的东西:
While True:
if new_connection:
launch_new_thread_for_it
3)记得在客户断开连接时发现情况!如果客户离开,检查是否有新数据是没有意义的。
答案 3 :(得分: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()
但我仍然无法弄清楚如何在我的网站上运行它。