我有一些测试客户端每次都遇到同样的问题。客户端可以连接,他们可以发送他们的第一条消息,但之后服务器停止响应该客户端。我怀疑这个问题与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()
服务器旨在通过本地网络访问,它需要重量轻,响应速度快,所以如果另一个实现(如基于线程)更好地满足这些要求,请告诉我。预期的应用程序将用作远程游戏键盘,因此需要低资源使用和高速度。
答案 0 :(得分:0)
直接使用socket
编写服务器会很困难。正如Keith所说,您需要以某种方式多路复用连接,例如select
或poll
或线程或fork
。您可能认为只需要一个连接,但是当出现打嗝和连接丢失时,您会怎么做?如果尚未意识到连接丢失,您的服务器是否能够响应来自客户端的重新连接尝试?
如果您的网络需求是基本的,那么您可以让其他东西处理所有的倾听,接受和分配给您的东西。您没有指定平台,但此类程序的示例在Mac OS上为launchd,在Linux上为xinetd。这些工具之间的细节不同,但基本上您在某些配置文件中配置它们以侦听某个端口上的连接。当他们得到它,他们负责设置连接,然后他们exec()
你的程序stdin
和stdout
瞄准套接字,所以你可以简单地使用所有的基本IO你可能已经知道print
和sys.stdin.read()
。
xinitd和launchd等解决方案的问题在于,对于每个新连接,他们必须fork()
和exec()
一个新的程序实例。这些操作相对较重,因此大量连接或高连接率可能会达到服务器的极限。但更糟糕的是,由于每个连接都在一个单独的过程中,因此很难在它们之间共享数据。此外,您可能发现在流程之间进行通信的大多数解决方案都涉及blocking API,现在您又回到了与select
或线程或类似的多路复用问题。
如果这不符合您的需求,我认为您最好学习使用更高级别的网络框架,该框架将处理您在socket
的路径上不可避免会遇到的所有问题。我建议的一个这样的框架是Twisted。除了处理处理连接的平凡细节,以及在它们之间复用IO的更复杂任务之外,您还将拥有一个庞大的工具库,可以更轻松地实现您的协议。