永远运行Python服务器

永远运行Python服务器,python,sockets,Python,Sockets,我正在尝试用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.bin

我正在尝试用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()
,以处理多个客户端,但问题实际上是在我的web服务器上运行它,让它永远等待连接


救救我~一方面,您的服务器将处理多个客户端,但一次只能处理一个客户端。这对于基于请求-响应的服务器(如HTTP服务器)来说并不坏。在您的情况下,您可能希望保持与每个客户端的开放连接

你可能想看看图书馆。此库将帮助您创建一个同时处理多个客户端的服务器。为此,可以使用ThreadingMixin

为该库提供的示例非常类似于聊天服务器,因此您可以使用它作为自己代码的基础

在服务器中,您需要创建已连接客户端的列表。您应该创建一个RequestHandler,它将在无限循环中从客户端读取传入数据。从客户端接收数据后,它应将数据发送到列表中的所有其他客户端。

简单问题。 1) 嵌套的while循环没有结束。因此,您将只从一个客户端接收数据。 2) 对于每个新连接,您可能需要单独的线程。比如:

While True:
    if new_connection:
        launch_new_thread_for_it

3) 记得在客户端断开连接时发现情况!如果客户端不存在,则检查是否有新数据没有意义。

要解决多客户端问题,请执行以下操作:

#!/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()

但是我仍然不知道如何在我的网站上运行它。

注意:这指的是初始代码示例,而不是后续的注释

因此,不确定您从哪个文档中提取了此代码示例。如果你能提供一个链接,那就太好了

我认为您可能需要更改这一行:

if not data: continue
为此:

if not data: break
据我回忆,“continue”将放弃执行其余语句,并立即返回循环的顶部,而“break”将返回循环的底部,这将允许其余逻辑关闭连接以完成其工作


据我所知,这将允许一个连接,然后在随后的连接尝试中似乎不做任何事情。我想这就是你所说的“永远运行”的意思。在“运行,但似乎不响应后续请求”中,没有?

“此服务器使用while循环,这意味着它应该只运行一次。”你是什么意思?
while True
循环将永远运行,而不仅仅是一次。您所说的“在我的web服务器上运行”是什么意思?@DavidRobinson该程序将运行一次,但将永远运行。@然后我将在没有外壳访问的远程服务器上运行它。这是一个很好的改进。您仍然需要向其他连接的客户端发送消息:-)若要在您的网站上运行,是否可以使用其他服务提供商?也许是虚拟linux主机或类似的东西?一般来说,web服务提供商将/不应允许您运行自己的服务器。@然后,我认为上面的
客户机
字典用于将消息发送到特定的客户机,或发送到所有人以获得广播消息。对于一个好的服务提供商,你有什么建议?是的,我也这么认为:-)AmazonEC2有虚拟linux服务器,但我没有使用该服务。我通常使用PaaS提供者,如Appengine或Heroku。也许Heroku还允许您运行自己的服务器。Heroku很容易安装和使用。@Hans然后我仔细考虑了一下,现在我正在使用设置我的应用程序。我还在安装客户端工具,但这应该不是什么大问题。好的,很酷。BTW,请考虑投票或接受你发现有用的答案。这也将帮助网站上的其他访问者。我正在尝试的是在任何我可以安装的web服务器上运行它。是的,terryjbates是对的。如果recv返回时没有任何数据,则连接将关闭。您将从一个关闭的连接继续读取。