我正在尝试创建一个使用多处理来处理客户端连接的服务器(当前是一个echo服务器)。
由于我希望能够在服务器出现故障时正确关闭与每个客户端的连接。我将所有连接添加到列表中,遗憾的是,我无法想到一种不会浪费时钟周期或在新客户端连接时更新列表的方法。从列表中删除已关闭的连接。
我很好,我将如何从列表中删除该过程,如下所示:
for i in xrange(len(sock.rProcesses)):
if not sock.rProcesses[i].is_alive():
del sock.rProcesses[i]
至于我的代码是:
from multiprocessing import Process
import socket, struct, sys, json
import settings
class ConnectionClient(Process):
conn = None
addr = None
def __init__(self, connection):
super(ConnectionClient, self).__init__()
self.conn, self.addr = connection
self.start()
print 'Connected with ' + self.addr[0] + ':' + str(self.addr[1])
def __send(self, info):
print 'sending %s' % info
self.conn.send(struct.pack('Q', len(info)))
self.conn.recv(1)
self.conn.send(info)
def __recv(self):
data = struct.unpack('Q', self.conn.recv(8))[0]
self.conn.send(' ')
return self.conn.recv(data)
def _close(self):
if self.conn != None:
self.conn.close()
print 'Disconnected with ' + self.addr[0] + ':' + str(self.addr[1])
del self.conn, self.addr
self.conn = None
def run(self):
while True:
try:data = json.loads(self.__recv())
except:break
if data[0] == 'QUIT':
break
else:
try:self.__send(json.dumps(data))
except:break
self._close()
#This is used by the with statement, so that I know that everything will close
#even if I ctrl-c in console.
class socketHandler(object):
s = None
rProcesses = []
def __enter__(self):
for res in socket.getaddrinfo(settings.host, settings.port,
socket.AF_UNSPEC, socket.SOCK_STREAM, 0,
socket.AI_PASSIVE):
af, socktype, proto, canonname, sa = res
try:
self.s = socket.socket(af, socktype, proto)
except socket.error as msg:
print msg
self.s = None
continue
try:
self.s.bind(sa)
self.s.listen(1)
except socket.error as msg:
print msg
self.s.close()
self.s = None
continue
break
return self
def __exit__(self, type, value, traceback):
print 'Closing Socket'
if self.s != None:
self.s.close()
for i in self.rProcesses:
if i.is_alive():
i._close()
del self.s
with socketHandler() as sock:
if sock.s == None:
print 'could not open socket'
sys.exit(1)
#Now I multithread the connections, not very well.
while True:
sock.rProcesses.append(ConnectionClient(sock.s.accept()))
我真的不知道在这里使用队列是一个好主意(我不知道他们做了什么)。我只能考虑使用多处理的while循环,或者在连接后检查,我个人也不想使用它们。或者我这样做是错的? (这是我的A2项目,所以我有点新手。)
服务器不允许在我的计算机上进行IPv4连接,因此如果您希望客户端和设置(只是本地主机和端口)在这里是一个链接:https://gist.github.com/Peilonrayz/ab693564145c53aa146c