在python中編寫socket服務端模塊(一):使用select

在linux上編寫socket服務端程序一般可以用select、poll、epoll三種方式,本文主要介紹使用select編寫socket服務端模塊與客戶端模塊。

服務器端程序代碼:

import socket
import select
import Queue

server=('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=10

while 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 socket
import 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 =0
for 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)

可以在編譯器中運行服務端程序,然後使用命令行方式運行客戶端程序進行測試。


發佈了22 篇原創文章 · 獲贊 13 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章