Python套接字 - 如何保持套接字保持活动状态?

11
我在Python中使用socket遇到了一些麻烦。当有人连接时,它能正常工作,但如果他们断开连接,则服务器程序会关闭。我希望在客户端关闭后,服务器程序仍然保持打开状态。我使用while True循环来保持连接存活,但一旦客户端关闭连接,服务器也会关闭连接。
以下是客户端的代码:
import socket, sys
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = sys.argv[1]
port = int(sys.argv[2])
conn.connect((host, port))

print("Connected to host " + sys.argv[1])
td = 1
while td == 1:
   msg = raw_input('MSG:  ')

这是服务器:

import socket, sys

socket.setdefaulttimeout(150)
host = ''               
port = 50005
socksize = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
print("Server started on port: %s" % port)
s.listen(1)
print("Now listening...\n")
conn, addr = s.accept()

while True:
    print 'New connection from %s:%d' % (addr[0], addr[1])
    data = conn.recv(socksize)
    if not data:
        break
    elif data == 'killsrv':
        conn.close()
        sys.exit()
    else:
       print(data)

1
你是否为n个连接使用了n+1个套接字?你需要一个始终监听的套接字。这个监听套接字接受新的连接请求,并在每次请求时打开另一个套接字。 - Penang
你能发一小段代码来演示问题吗? - SimonJ
n+1个套接字?不确定我是否理解正确。您能再解释一下吗? - AustinM
1
如果你想完成任何事情,至少要使用一个 socketserver - Jochen Ritzel
2个回答

10
如果客户端关闭连接,您希望它关闭套接字。
看起来这里有一点不连贯,我将尝试阐述一下。当您创建套接字、绑定并侦听时,您已经为其他人建立了一个开放的门,让他们来连接您。
一旦客户端连接到您,您使用accept()调用接受连接并获取一个新的套接字(conn),该套接字返回供您与客户端进行交互。您原始的监听套接字仍然存在且处于活动状态,您仍然可以使用它来接受更多的新连接。
查看您的代码,您可能想要做类似这样的事情:
while True:
    print("Now listening...\n")
    conn, addr = s.accept()

    print 'New connection from %s:%d' % (addr[0], addr[1])
    data = conn.recv(socksize)
    if not data:
        break
    elif data == 'killsrv':
        conn.close()
        sys.exit()
    else:
        print(data)

请注意,这只是一个起点,正如其他人建议的那样,您可能需要使用select(),并分叉进程或生成线程来为每个客户端提供服务。

谢谢,这个似乎起作用了,但我遇到了另一个问题。如果我不断发送消息,客户端最终会冻结。不知道为什么。 - AustinM
你能详细说明一下你的客户端代码以及它是如何发送数据的吗? - Jeff

3

您的代码只接受一个连接 - 循环仅处理第一个接受的连接,并在失去连接后立即终止。这就是您的服务器存在的方式:

data = conn.recv(socksize)
if not data:
    break

你需要做的是接受多个连接,同时在它们各自的循环中进行处理。请注意,对于每个套接字,不一定要使用真正的循环,你可以使用基于select的方法来查询哪个套接字与事件相关联(例如可用数据、连接丢失等),然后仅处理这些套接字,全部在同一个循环中进行。
你也可以使用多线程/多进程方法,处理每个客户端都在各自的线程或进程中 - 我想当你进行尝试时,不会遇到扩展问题。
参见:

http://docs.python.org/library/select.html

http://docs.python.org/library/multiprocessing.html


1
谢谢。你能否给我一个使用套接字进行选择的例子? - AustinM
@AustinM 我同意 - cascading-style
@cascading-style 我也同意。 - qtwrk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接