您的位置:首页 > 编程语言 > Python开发

python中使用epoll开发服务端程序

2014-04-18 16:11 393 查看
转自:http://www.cnblogs.com/dkblog/archive/2011/03/25/1995755.html

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: