select —— poll —— epoll

 
import socket,select
s=socket.socket()
s.setblocking(False)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(('127.0.0.1',6666))
s.listen()
rlist=[s,]
wlist=[]
erlist=[]
while True:
    rs,ws,er=select.select(rlist,wlist,erlist)
    print(1)
    for i in rs:
        if i is s:
            con,add=s.accept()
            rlist.append(con)
        else:
            date=i.recv(1024)
            if not date:
                rlist.remove(i)
            print(date.decode())
            i.send(date)
    for i in erlist:
        print(i)
View Code ——select 服务端
import socket,select,time
s=socket.socket()
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(('127.0.0.1',6666))
s.listen()
poll=select.poll()
poll_dic={s.fileno(): s,}
poll.register(s, select.POLLIN | select.POLLERR)
while True:
    try:
        events=poll.poll()
        for fd,event in events:
            print(fd,event)
            if fd == s.fileno():
                con,add=s.accept()
                poll_dic[con.fileno()] = con
                poll.register(con,select.POLLIN | select.POLLERR)
            elif event == select.POLLIN:

                date = poll_dic[fd].recv(1024)
                print(date.decode())
                if not date:
                    print('进来了')
                    poll.unregister(fd)
                    poll_dic[fd].close()
                    del poll_dic[fd]

    except:
        poll.unregister(s)
View Code ——poll 服务端
import socket,select
s=socket.socket()
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(('127.0.0.1',6666))
s.listen()
poll=select.poll()
poll_dict={s.fileno():s}
def a(fd):
    poll.unregister(fd)
    poll_dict[fd].close()
    del poll_dict[fd]

def main():
    poll.register(s,select.POLLIN | select.POLLERR)
    while True:
        p=poll.poll()
        for fd,event in p:
            if fd == s.fileno():
                con, addr = s.accept()
                poll.register(con, select.POLLIN | select.POLLERR)
                poll_dict[con.fileno()]=con
            elif event == select.POLLIN:
                date=poll_dict[fd].recv(1024)
                if not date:
                    a(fd)
                    continue
                print(date.decode(),111)
                poll_dict[fd].send(date)
            elif event == select.POLLERR:
                a(fd)
if __name__ == '__main__':
    main()
View Code ——POLL加一服务端

 

#使用poll改为epoll,更改创建模式,更改对应的事件名即可 
import socket,select,time
s=socket.socket()
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(('127.0.0.1',6666))
s.listen()
poll=select.epoll()
poll_dic={s.fileno(): s,}
poll.register(s, select.EPOLLIN | select.EPOLLERR)
while True:
    try:
        events=poll.poll()
        for fd,event in events:
            print(fd,event,'123213123')
            print(fd,event)
            if fd == s.fileno():
                con,add=s.accept()
                poll_dic[con.fileno()] = con
                poll.register(con,select.EPOLLIN | select.EPOLLERR)
            elif event == select.EPOLLIN:
                date = poll_dic[fd].recv(1024)
                print(date.decode())
                if not date:
                    print('进来了')
                    poll.unregister(fd)
                    poll_dic[fd].close()
                    del poll_dic[fd]
                poll_dic[fd].send(date)
    except:
        poll.unregister(s)
View Code 【poll 改为 epoll方法】

 

import socket,selectors
s=socket.socket()
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(('127.0.0.1',6666))
s.listen()
epoll=selectors.DefaultSelector()
def accept_(s):
    con,addr=s.accept()
    epoll.register(con,selectors.EVENT_READ,recv_)

def recv_(con):
    try:
        date=con.recv(1024)
        if not date:
            raise ''
        print(date.decode())
        con.send(date)
    except:
        epoll.unregister(con)
        con.close()
        print('断开连接')

def main():
    epoll.register(s,selectors.EVENT_READ,accept_)
    while True:
        s_eoll=epoll.select()# #检测所有的fileobj,是否有完成wait data的
        for key,mask in s_eoll:
            ac=key.data   #这是绑定事件函数,文件指针accept_
            print(key,'这是KEY')
            ac(key.fileobj,mask)#拿sock对象文件描述符(fd)
if __name__ == '__main__':
    main()
View Code epoll-使用selectos模块

 

 

# 写一个聊天室
# 功能:类似QQ
# 1,进入聊天室需要输入姓名,姓名不能重复
# 2 有人进入聊天室会向其他人发送通知
# 3 一个发消息,其他人会收到消息
# 4 某人退出聊天室,其他人也会收到通知,
###服务端
import socket,select,time
epoll=select.epoll()
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

socket_dict={s.fileno():s}
epoll.register(s.fileno(),select.EPOLLIN | select.EPOLLERR)
s.bind(('127.0.0.1',6666))
s.listen()
list_dict={}
while True:
    event=epoll.poll()
    for fd,event_ in event:
        if fd == s.fileno():
            con,addr = s.accept()
            socket_dict[con.fileno()]=con
            epoll.register(con.fileno(),select.EPOLLIN | select.EPOLLERR)
        elif event_ == select.EPOLLIN:
            date = socket_dict[fd].recv(1024)
            if not date:# 处理断开的连接 _收尸处理
                epoll.unregister(socket_dict[fd].fileno())
                socket_dict[fd].close()
                try:
                    for i in list_dict:
                        if fd == i :
                            continue

                        #print(list_dict[fd])
                        exit_name = (list_dict[fd]+'退出').encode()
                        socket_dict[i].send(exit_name)

                    #print('发送完成')
                    del list_dict[fd]
                    del socket_dict[fd]
                    continue
                except :print('重复姓名客户端连接 ')
            else:
                if fd not in list_dict: #判断FD在不在list_dict,不在则进入存入fd:name
                    date_de = date.decode()#获取发送过来的名字
                    if date_de not in list_dict.values(): #判断列表内是否有重复name
                        socket_dict[fd].send('没有重复姓名'.encode())
                        for i in list_dict:#遍历文件描述符
                            try:
                                date_de_1 = ('\n'+date_de+'加入!').encode()
                                socket_dict[i].send(date_de_1)
                            except:
                                print('此时出错')
                        list_dict[fd] = date_de
                    else:
                        #print(date_de)
                        socket_dict[fd].send('重复姓名'.encode())
                else:
                    #print('这是list_dict',list_dict)# fd 在list_dict中,循环发送接收到的信息
                    for i in list_dict:
                        if i == fd:
                            pass
                        else:
                            date_2=('\n%s说:'%list_dict[fd]).encode()+date
                            socket_dict[i].send(date_2)

#客户端,使用简单的多进程fork() 来完工

import socket,time,os,sys
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
inp = ''
try:
    while not inp:
        inp = input('进行连接,请输入名:').encode()
except KeyError:
    exit()
try:
    s.connect(('127.0.0.1',6666))
    s.send(inp)
    verify = s.recv(1024).decode()
    try:
        if verify == '重复姓名':
            raise verify
    except:
        print(verify)
        exit()
except:
    print('连接失败')
    exit()
def send_msg(s):
    try:
        while True:
            inp = input('输入内容:')
            if inp == '':
                continue
            elif inp == 'q':
                sys.exit(1)
            inp = inp.encode()
            s.send(inp)
    except  KeyboardInterrupt:
        sys.exit()
def recv_msg(s):
    while True:
        time.sleep(1)
        date=s.recv(1024).decode()
        print(date+'\n输入内容:',end='')
        pid,status= os.waitpid(-1,os.WNOHANG)
        #print('pid',pid,status)
        if pid != 0:
            sys.exit()

pid = os.fork()
if pid < 0 :
    print('创建失败')
elif pid == 0:
    send_msg(s)
else:
    recv_msg(s)

 



 

posted @ 2018-09-08 12:51  Sky__liu  阅读(245)  评论(0编辑  收藏  举报