【问题标题】:Trouble with a Python serverPython服务器的问题
【发布时间】:2012-12-31 12:31:09
【问题描述】:

我有几个测试客户端每次都遇到相同的问题。客户端可以连接,并且可以发送第一条消息,但之后服务器停止响应该客户端。我怀疑这个问题与 s.accept() 有关,但我不确定到底出了什么问题或如何解决它。

def startServer():
    host = ''
    port = 13572
    backlog = 5
    size = 1024

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((host,port))
    s.listen(backlog)

    print "Close the command prompt to stop Gamelink"

    while 1:
        try:
            client, address = s.accept()
            data = client.recv(size)
            if data:
                processData(data)
                client.send("OK")
            else:
                print "Disconnecting from client at client's request"
                client.close()
        except socket.error, (value, message):
            if s:
                print "Disconnecting from client, socket issue"
                s.close()
            print "Error opening socket: " + message
            break
        except:
            print "Gamelink encountered a problem"
            break
        print "End of loop"
    client.close()
    s.close()

服务器旨在通过本地网络访问,并且它需要重量轻且响应速度非常快,因此如果其他实现(例如基于线程)会更好地满足这些要求,请告诉我。预期的应用程序将用作远程游戏键盘,因此需要低资源使用和高速。

【问题讨论】:

  • 您应该将accept 放在循环之外。此外,此服务器将只接受一个连接。如果您想要一个服务于多个客户端的真实服务器,您将需要多路复用连接,例如使用selectpoll
  • 一个连接实际上非常适合我正在尝试做的事情,看起来这解决了我的问题。谢谢!

标签: python sockets keep-alive


【解决方案1】:

直接使用socket 编写服务器会很困难。正如基思所说,您需要以某种方式多路复用连接,例如使用selectpoll 或线程或fork。您可能认为您只需要一个连接,但是当出现问题并且连接丢失时您会怎么做?如果您的服务器尚未意识到连接丢失,它是否能够响应来自客户端的重新连接尝试?

如果您的网络需求是基本的,您也许可以让其他东西为您处理所有的倾听、接受和分叉的事情。您没有指定平台,但此类程序的示例是 Mac OS 上的 launchd 和 Linux 上的 xinetd。这些工具之间的细节有所不同,但基本上你可以在一些配置文件中配置它们,以侦听某个端口上的连接。当他们得到它时,他们负责建立连接,然后他们exec() 你的程序用stdinstdout 瞄准套接字,所以你可以简单地使用你可能已经知道的所有基本IO,比如@987654332 @和sys.stdin.read()

xinitd 和launchd 等解决方案的问题在于,对于每个新连接,它们必须fork()exec() 一个新的程序实例。这些是相对繁重的操作,因此大量连接或高新连接率可能会达到服务器的限制。但更糟糕的是,由于每个连接都处于单独的进程中,因此很难在它们之间共享数据。此外,您可能会发现在进程之间进行通信的大多数解决方案都涉及blocking API,现在您又回到了与select 或线程或类似的多路复用问题。

如果这不能满足您的需求,我认为您最好学习使用更高级别的网络框架,该框架将处理您在走socket 的道路时不可避免地遇到的所有问题。我建议的一个这样的框架是Twisted。除了处理连接处理的普通细节以及在它们之间多路复用 IO 的更复杂任务之外,您还将拥有一个庞大的工具库,这将使您的协议的实现变得更加容易。

【讨论】:

    猜你喜欢
    • 2022-07-25
    • 2011-06-06
    • 1970-01-01
    • 2012-10-03
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    • 1970-01-01
    相关资源
    最近更新 更多