zoukankan      html  css  js  c++  java
  • 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 = ('
    '+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=('
    %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+'
    输入内容:',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)


  • 相关阅读:
    c#中获取服务器IP,客户端IP以及Request.ServerVariables详细说明
    无废话MVC入门教程二[第一个小Demo]
    winform使用xml作为数据源
    SQL Server 2005为数据库设置用户名和密码的方法
    数据库 的版本为 661,无法打开。此服务器支持 655 版及更低版本。不支持降级路径。
    Visual Studio快速封装字段方法
    erp crm oa
    sqldbhelper
    OleDbHelper
    存储过程分页(3)
  • 原文地址:https://www.cnblogs.com/Skyda/p/9608909.html
Copyright © 2011-2022 走看看