select版tcp服务器(python实现)
在编写了单进程非阻塞式服务器之后,还有另外种写服务器的方法,便是利用select。
select是对底层操作系统的一个访问操作,因而效率较高,比单进程非阻塞中的for循环遍历效率要高,可以利用select进行选择,选择出来可以读取信息的套接字、可以发送信息的套接字、以及产生的异常(分别是三个返回值)。
readable, writable, exceptionable = select([], [], [])
以上即为select的使用方法,程序执行到该语句后进行阻塞等待,接收到新的套接字之后便解阻塞。
程序思路便是利用select检测、选择出能读取的套接字(包括服务器套接字、客户端套接字),将接收到消息的客户端套接字存入列表(列表中本来只有服务器套接字),之后进行for循环遍历,读取套接字中的信息或者进行与客户端的连接。
代码如下:
#-*- coding:utf-8 -*-
from socket import *
from select import select
import sys
def main():
serSocket = socket(AF_INET, SOCK_STREAM)
localAddr = ('', 7788)
serSocket.bind(localAddr)
serSocket.setblocking(False)
serSocket.listen(100)
inputs = [serSocket]
running = True
while True:
readable, writable, exceptionable = select(inputs, [], [])
for sock in readable:
if sock == serSocket:
clientSocket, clientAddr = serSocket.accept()
print('newClient[%s]'%str(clientAddr))
inputs.append(clientSocket)
elif sock == sys.stdin:
cmd = sys.stdin.readline()
running = False
break
else:
massage = sock.recv(1024)
if massage:
print('massage from [%s] is %s'%(str(sock), massage.decode('utf-8')))
else:
print('[%s] was closed'%(str(sock)))
inputs.remove(sock)
sock.close()
if not running:
break
serSocket.close()
if __name__ == '__main__':
main()
select版服务器有一定的缺点,便是只能处理1024个并发客户端,因而其效率还是有一定的局限性。
还没有评论,来说两句吧...