zoukankan      html  css  js  c++  java
  • python中使用epoll开发服务端程序

    Python代码:
    import socket, logging
    import select, errno

    logger = logging.getLogger("network-server")

    def InitLog():
        logger.setLevel(logging.DEBUG)

        fh = logging.FileHandler("network-server.log")
        fh.setLevel(logging.DEBUG)
        ch = logging.StreamHandler()
        ch.setLevel(logging.ERROR)
       
        formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
        ch.setFormatter(formatter)
        fh.setFormatter(formatter)
       
        logger.addHandler(fh)
        logger.addHandler(ch)


    if __name__ == "__main__":
        InitLog()
       
        try:
            listen_fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
        except socket.error, msg:
            logger.error("create a socket failed")
       
        try:
            listen_fd.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        except socket.error, msg:
            logger.error("setsocketopt error")
       
        try:
            listen_fd.bind(('', 2003))
        except socket.error, msg:
            logger.error("listen file id bind ip error")
       
        try:
            listen_fd.listen(10)
        except socket.error, msg:
            logger.error(msg)
       
        try:
            epoll_fd = select.epoll()
            epoll_fd.register(listen_fd.fileno(), select.EPOLLIN)
        except select.error, msg:
            logger.error(msg)
           
        connections = {}
        addresses = {}
        datalist = {}
        while True:
            epoll_list = epoll_fd.poll()
            for fd, events in epoll_list:
                if fd == listen_fd.fileno():
                    conn, addr = listen_fd.accept()
                    logger.debug("accept connection from %s, %d, fd = %d" % (addr[0], addr[1], conn.fileno()))
                    conn.setblocking(0)
                    epoll_fd.register(conn.fileno(), select.EPOLLIN | select.EPOLLET)
                    connections[conn.fileno()] = conn
                    addresses[conn.fileno()] = addr
                elif select.EPOLLIN & events:
                    datas = ''
                    while True:
                        try:
                            data = connections[fd].recv(10)
                            if not data and not datas:
                                epoll_fd.unregister(fd)
                                connections[fd].close()
                                logger.debug("%s, %d closed" % (addresses[fd][0], addresses[fd][1]))
                                break
                            else:
                                datas += data
                        except socket.error, msg:
                            if msg.errno == errno.EAGAIN:
                                logger.debug("%s receive %s" % (fd, datas))
                                datalist[fd] = datas
                                epoll_fd.modify(fd, select.EPOLLET | select.EPOLLOUT)
                                break
                            else:
                                epoll_fd.unregister(fd)
                                connections[fd].close()
                                logger.error(msg)
                                break       
                elif select.EPOLLHUP & events:
                    epoll_fd.unregister(fd)
                    connections[fd].close()
                    logger.debug("%s, %d closed" % (addresses[fd][0], addresses[fd][1]))
                elif select.EPOLLOUT & events:
                    sendLen = 0            
                    while True:
                        sendLen += connections[fd].send(datalist[fd][sendLen:])
                        if sendLen == len(datalist[fd]):
                            break
                    epoll_fd.modify(fd, select.EPOLLIN | select.EPOLLET)                
                else:
                    continue

     客户端程序,Python代码:

    import socket
    import time
    import logging

    logger = logging.getLogger("network-client")
    logger.setLevel(logging.DEBUG)

    fh = logging.FileHandler("network-client.log")
    fh.setLevel(logging.DEBUG)
    ch = logging.StreamHandler()
    ch.setLevel(logging.ERROR)

    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    ch.setFormatter(formatter)
    fh.setFormatter(formatter)

    logger.addHandler(fh)
    logger.addHandler(ch)

    if __name__ == "__main__":
        try:
            connFd = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
        except socket.error, msg:
            logger.error(msg)
       
        try:
            connFd.connect(("192.168.31.226", 2003))
            logger.debug("connect to network server success")
        except socket.error,msg:
            logger.error(msg)
       
        for i in range(1, 11):
            data = "The Number is %d" % i
            if connFd.send(data) != len(data):
                logger.error("send data to network server failed")
                break
            readData = connFd.recv(1024)
            print readData
            time.sleep(1)
       
        connFd.close()

     这是个很简单的C/S模型的程序,流程其实和C语言相差不大,就是为了学学python中的基本语法,以及logging,select,socket模块的使用。客户端发送字符串,服务端再将该字符串返回客户端,epoll中使用的边缘触发。

    这个有一篇很权威的文章讲这个
    http://scotdoyle.com/python-epoll-howto.html
    附件

  • 相关阅读:
    Pytest单元测试框架之FixTure内置临时文件tmpdir操作
    Python+Request库+第三方平台实现验证码识别示例
    Pytest单元测试框架之parametrize参数化
    Pytest单元测试框架之setup/teardown模块示例操作
    mysql匿名账户登录导致的"ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql'"错误
    求全排列
    (转载)你真的会写单例模式吗——Java实现
    《大话设计模式》之--第14章 老板回来,我不知道----观察者模式
    关于java Integer大小比较的问题
    Java char[] 数组转为 String 的两种方式
  • 原文地址:https://www.cnblogs.com/dkblog/p/1995755.html
Copyright © 2011-2022 走看看