这是个很简单的C/S模型的程序,流程其实和C语言相差不大,客户端发送字符串,服务端再将该字符串返回客户端,epoll中使用的边缘触发。
-
#服务端代码 -
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()
这个有一篇很权威的文章讲这个
http://scotdoyle.com/python-epoll-howto.html
附件
来源:oschina
链接:https://my.oschina.net/u/4000302/blog/3076335