python socket select IO多路复用 sockeserver简单使用

1.IO多路复用 select(有最大连接数限制),pool(没有最大连接数限制),epool(异步)

服务器端:

import socket
import select

sscok = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sscok.bind(('127.0.0.1',8888))
sscok.listen(5)
inputs = [sscok,]
while True:
    r_list,w_list,e_list = select.select(inputs,[],[],1)
    print('正在监听的%s个对象'%len(inputs))
    print(r_list)
    for sk in r_list:
        if sk == sscok:
            conn,addr = sk.accept()
            inputs.append(conn)
        else:
            try:
                data = sk.recv(1024)
                sk.sendall(data)
            except Exception as e:
                inputs.remove(sk)
sscok.close()

客户端:

import socket
csock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
csock.connect(('127.0.0.1',8888,))
while True:
    data = input('请输入要输入的内容')
    csock.sendall(bytes(data,encoding='utf-8'))
    data = csock.recv(1024)
    print(str(data,encoding='utf-8'))
csock.close()

 读写分离,实现伪并发 :服务器端如下,客户端不变

#!/usr/bin/env python
# --*-- encoding:utf-8 --*--
import socket
import select
# 这种方式:同时接听了多个电话,哪个电话发出了声音,就回复哪个电话
sscok = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sscok.bind(('127.0.0.1',8888))
sscok.listen(5)
#用于消息的读
inputs = [sscok,]
#用于消息的写
outputs = []
#用于读写分离是,消息的存放
dicta = {}
while True:
    # 如果inputs里面发生变化时,会添加到r_list, outputs所有元素添加到w_list,出错的放在e_list
    r_list,w_list,e_list = select.select(inputs,outputs,inputs,1)
    #当有客户端连接是对象+1
    print('正在监听的%s个对象'%len(inputs))
    #当inputs变化时,r_list存放变化的那一个元素
    print(r_list)
    
    for sk in r_list:  #消息的读
        if sk == sscok:  #客户端的连接,变化的是sscok
            conn,addr = sk.accept()  #接受客户的连接
            inputs.append(conn)   #将连接返回的socket对象添加到监听列表中
            dicta[conn] = []  #在字典中添加一个conn:空列表
        else:   #客户端发送过消息,变化的conn,此时conn已经添加到监听列表
            try:
                data = sk.recv(1024)  #接收消息
                dicta[sk].append(str(data,encoding='utf-8')) #更新字典
                outputs.append(sk)  #添加到outputs,方便后面的写
                # sk.sendall(data)
            except Exception as e:
                inputs.remove(sk)  #客户端中断,将对应的连接删除

    for sk in w_list: #消息的写
        recv_str = dicta[sk][0] #读取字典
        del dicta[sk][0]  #删除字典的元素
        sk.sendall(bytes('自动回复:'+recv_str,encoding='utf-8')) # 向outputs里面元素发送消息
        outputs.remove(sk) #发送完消息,删除outputs元素

    for sk in e_list:
        inputs.remove(sk) #连接异常,则删除这个连接

sscok.close()

 2.上面实现的是一种伪并发的情况,真正要实现多线程并发,需要利用socketserver模块

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import SocketServer

class MyServer(SocketServer.BaseRequestHandler):
    def handle(self):
     //some method....

if __name__='__main__':
    server = SocketServer.ThreadingTCPServer(('127.0.0.1,9999'),MyServer)
    server.serve_forever()
  • 自定义一个类,继承chenSocketServer.BaseRequestHandler,并重写handle方法
  • 通过访问self.request ,就可以访问到连接过来的socket对象
posted @ 2017-05-05 14:05  1916  阅读(122)  评论(0)    收藏  举报