在python中编写socket服务端模块(一):使用select

来源:互联网 发布:银行家算法代码 编辑:程序博客网 时间:2024/06/15 02:44

在linux上编写socket服务端程序一般可以用select、poll、epoll三种方式,本文主要介绍使用select编写socket服务端模块与客户端模块。

服务器端程序代码:

import socketimport selectimport Queueserver=('10.0.2.15',21345)#SOCK_STREAM(流套接字)、SOCK_DGRAM(数据报文套接字)、AF_INET(IPv4)sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#阻塞与端口复用前后顺序可换sock.setblocking(False)#SOL_SOCKET(套接字描述符)、SO_REUSEADDR(端口复用)sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)sock.bind(server)sock.listen(5)rlists=[sock]wlists=[]msg_que={}timeout=10while True:     rs,ws,es=select.select(rlists,wlists,rlists,timeout)    if not(rs or ws or es):        print 'timeout...'        continue        #读部分    for s in rs:        #看s是否是本机上用于监听的socket,是则接受连接,不是则接收数据        if s is sock:            conn,addr=s.accept()            #conn、addr分别是所接收到的socket对象和对方端口            print 'connect by',addr            conn.setblocking(False)            rlists.append(conn)            #使用字典将conn与一个队列相对应            msg_que[conn]=Queue.Queue()                    else:            data =s.recv(1024)            if data:                print data                msg_que[s].put(data)                if s not in wlists:                    wlists.append(s)            else:                if s in wlists:                    wlists.remove(s)                rlists.remove(s)                s.close                del msg_que[s]    #写部分               for  s in ws:        try:            #get_nowait()跟get(0)一样            msg=msg_que[s].get_nowait()        except Queue.Empty:            print 'msg empty'            wlists.remove(s)        else:            s.send(msg)    #异常部分        for s in es:        print 'except',s.getpeername()        if s in rlists:            rlists.remove(s)        if s in wlists:            wlists.remove(s)                s.close        del msg_que[s]    

客服端程序代码:

# -*- coding: utf-8 -*-  #使用utf-8在命令行窗口里才能运行import socketimport time#getpeername()获得socket对方的地址server=('10.0.2.15',21345)msg=['hello','welcome','xiaoming','zhangsan','list','liuliu']socks=[]for i in range(10):    sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)    socks.append(sock)    for s in socks:    s.connect(server)counter =0for m in msg:    for s in socks:        s.send('%d send %s' %(counter,m))        counter=counter+1    for s in socks:        data =s.recv(1024)        print '%s echo %s' %(s.getpeername(),data)        if not data:            s.close()    time.sleep(2)

可以在编译器中运行服务端程序,然后使用命令行方式运行客户端程序进行测试。