最近在学Python,结合专业选取网络作为入口,用面向对象的思维去写TCP网络通信的程序,弄了三天也没搞清楚如何使用底层的socket优雅的实现多任务、多用户的TCP通信,后来看到这段代码,感觉作者思路明确,代码优雅,利用双向通信很好的抽象的TCP服务器端通信,作者使用inputs ,outputs分别描述了TCP通道的输出、输出,同时使用inputs[SocketClient] ,outputs[SocketClient]描述了每个用户连接的通道并建立起了双向通道的正确对应关系,真是设计的太好了;对于多用户则使用了select.select(intputs, outputs, [] ,timeout)进行轮询操作,层次感分明。代码如下:
encoding = 'utf-8'
import socket
from Queue import Queue
import select
def TcpServer(address=('',28000), blokblog=5):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
server.setblocking(False)
server.bind(address)
server.listen(blokblog)
inputs = [server]
outputs = []
msg_queque = {}
timeout = 20
while inputs:
"""
select初始的触发由inputs = [server]完成
inputs[socketclient], outputs[socketclient]建立起一一对应的关系
"""
readable, writeable, excetable = select.select(inputs, outputs, [], timeout)
if not (readable or writeable or excetable):
break
for s in readable:
if s is server:
sock, add = s.accept()
sock.setblocking(False)
"""
新增一个客户端,inputs赋值,select检测到inputs发生变化
新增一个SocketClient
"""
inputs.append(sock)
msg_queque[sock] = Queue()
sock.send('welcome')
print 'new connection is', add
else:
data = s.recv(1024)
if data:
print data
"""
此处通过queque[SocketClient]建立起客户及数据的对应关系
Map??
"""
msg_queque[s].put(data)
"""
outputs有没有发生变化是人为控制,此处给outputs赋值可以让select检测其发生变化
赋值内容为SocketClient
"""
if s not in outputs:
outputs.append(s)
else:
"""
移动某个连接时,须移除建立的通道(双向),及通道间的消息队列
"""
if s in outputs:
outputs.remove(s)
inputs.remove(s)
s.close()
del msg_queque[s]
for s in writeable:
try:
next_msg = msg_queque[s].get_nowait()
except:
pass
else:
s.send(next_msg)
if __name__=='__main__':
TcpServer()