1. 程式人生 > >Python中使用epoll開發服務端程式

Python中使用epoll開發服務端程式

這是個很簡單的C/S模型的程式,流程其實和C語言相差不大,客戶端傳送字串,服務端再將該字串返回客戶端,epoll中使用的邊緣觸發。

 

 
  1. #服務端程式碼

  2. import socket, logging

  3. import select, errno

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

  6.  
  7. def InitLog():

  8. logger.setLevel(logging.DEBUG)

  9.  
  10. fh = logging.FileHandler("network-server.log")

  11. fh.setLevel(logging.DEBUG)

  12. ch = logging.StreamHandler()

  13. ch.setLevel(logging.ERROR)

  14.  
  15. formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")

  16. ch.setFormatter(formatter)

  17. fh.setFormatter(formatter)

  18.  
  19. logger.addHandler(fh)

  20. logger.addHandler(ch)

  21.  
  22.  
  23. if __name__ == "__main__":

  24. InitLog()

  25.  
  26. try:

  27. listen_fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)

  28. except socket.error, msg:

  29. logger.error("create a socket failed")

  30.  
  31. try:

  32. listen_fd.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

  33. except socket.error, msg:

  34. logger.error("setsocketopt error")

  35.  
  36. try:

  37. listen_fd.bind(('', 2003))

  38. except socket.error, msg:

  39. logger.error("listen file id bind ip error")

  40.  
  41. try:

  42. listen_fd.listen(10)

  43. except socket.error, msg:

  44. logger.error(msg)

  45.  
  46. try:

  47. epoll_fd = select.epoll()

  48. epoll_fd.register(listen_fd.fileno(), select.EPOLLIN)

  49. except select.error, msg:

  50. logger.error(msg)

  51.  
  52. connections = {}

  53. addresses = {}

  54. datalist = {}

  55. while True:

  56. epoll_list = epoll_fd.poll()

  57. for fd, events in epoll_list:

  58. if fd == listen_fd.fileno():

  59. conn, addr = listen_fd.accept()

  60. logger.debug("accept connection from %s, %d, fd = %d" % (addr[0], addr[1], conn.fileno()))

  61. conn.setblocking(0)

  62. epoll_fd.register(conn.fileno(), select.EPOLLIN | select.EPOLLET)

  63. connections[conn.fileno()] = conn

  64. addresses[conn.fileno()] = addr

  65. elif select.EPOLLIN & events:

  66. datas = ''

  67. while True:

  68. try:

  69. data = connections[fd].recv(10)

  70. if not data and not datas:

  71. epoll_fd.unregister(fd)

  72. connections[fd].close()

  73. logger.debug("%s, %d closed" % (addresses[fd][0], addresses[fd][1]))

  74. break

  75. else:

  76. datas += data

  77. except socket.error, msg:

  78. if msg.errno == errno.EAGAIN:

  79. logger.debug("%s receive %s" % (fd, datas))

  80. datalist[fd] = datas

  81. epoll_fd.modify(fd, select.EPOLLET | select.EPOLLOUT)

  82. break

  83. else:

  84. epoll_fd.unregister(fd)

  85. connections[fd].close()

  86. logger.error(msg)

  87. break

  88. elif select.EPOLLHUP & events:

  89. epoll_fd.unregister(fd)

  90. connections[fd].close()

  91. logger.debug("%s, %d closed" % (addresses[fd][0], addresses[fd][1]))

  92. elif select.EPOLLOUT & events:

  93. sendLen = 0

  94. while True:

  95. sendLen += connections[fd].send(datalist[fd][sendLen:])

  96. if sendLen == len(datalist[fd]):

  97. break

  98. epoll_fd.modify(fd, select.EPOLLIN | select.EPOLLET)

  99. else:

  100. continue

  101. #客戶端程式,Python程式碼:

  102.  
  103. import socket

  104. import time

  105. import logging

  106.  
  107. logger = logging.getLogger("network-client")

  108. logger.setLevel(logging.DEBUG)

  109.  
  110. fh = logging.FileHandler("network-client.log")

  111. fh.setLevel(logging.DEBUG)

  112. ch = logging.StreamHandler()

  113. ch.setLevel(logging.ERROR)

  114.  
  115. formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")

  116. ch.setFormatter(formatter)

  117. fh.setFormatter(formatter)

  118.  
  119. logger.addHandler(fh)

  120. logger.addHandler(ch)

  121.  
  122. if __name__ == "__main__":

  123. try:

  124. connFd = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)

  125. except socket.error, msg:

  126. logger.error(msg)

  127.  
  128. try:

  129. connFd.connect(("192.168.31.226", 2003))

  130. logger.debug("connect to network server success")

  131. except socket.error,msg:

  132. logger.error(msg)

  133.  
  134. for i in range(1, 11):

  135. data = "The Number is %d" % i

  136. if connFd.send(data) != len(data):

  137. logger.error("send data to network server failed")

  138. break

  139. readData = connFd.recv(1024)

  140. print readData

  141. time.sleep(1)

  142.  
  143. connFd.close()

 

這個有一篇很權威的文章講這個
http://scotdoyle.com/python-epoll-howto.html