python使用epoll实现服务端的方法

作者:linux_c_coding_man 时间:2021-05-16 22:52:34 

如下所示:


#!/usr/bin/python
# -*- coding: UTF-8 -*-
import socket
import select

send_data = "hello world!"
send_len = len(send_data)
recv_len = 1024
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
addr = ("0.0.0.0", 8765)
tcp_socket.bind(addr)
tcp_socket.listen(5)
tcp_socket.setblocking(False)
epoll = select.epoll()
'''(边缘触发)select.EPOLLIN | select.EPOLLET'''
epoll.register(tcp_socket.fileno(), select.EPOLLIN)
'''因为epoll返回的触发事件对应的是套接字文件描述符,所以需要在字典中加入对应关系'''
fd_to_socket = {tcp_socket.fileno():tcp_socket}

while True :
events = epoll.poll(-1)
for fd, event in events:
 fd_socket = fd_to_socket[fd]
 if fd == tcp_socket.fileno():
  while True:
   try:
    new_socket, new_addr = fd_socket.accept()
   except socket.error as e:
    (errno, err_msg) = e
    print errno
    print err_msg
    if errno == 11:
     break
   print "new accpet:", new_addr
   new_socket.setblocking(False)
   new_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
   epoll.register(new_socket.fileno(), select.EPOLLIN)
   fd_to_socket[new_socket.fileno()] = new_socket
 elif event&select.EPOLLIN:
  recv_datas = []
  recd = 0
  while (recd < recv_len):
   try:
    recv_data = fd_socket.recv(recv_len - recd)
    '''处理读的正常关闭'''
    if recv_data == "":
     print "close socket"
     epoll.unregister(fd)
     fd_to_socket[fd].close()
     del fd_to_socket[fd]
     break
    else:
     recv_datas.append(recv_data)
     recd = recd + len(recv_data)
   '''处理异常关闭(EAGAIN,EINTR)'''
   except socket.error as e:
    (errno, err_msg) = e
    print errno
    print err_msg
    '''因为用的水平触发,EAGAIN我们跳出循环,等待下次触发再读就好了'''
    if errno == 11:
     break
    '''软中断打断了还要继续读'''
    elif errno == 4:
     continue
    '''其它错误我们直接关闭套接字'''
    else:
     print "close socket"
     epoll.unregister(fd)
     fd_to_socket[fd].close()
     del fd_to_socket[fd]
     break
   print repr(recv_datas)
   total_send = 0
   while total_send < send_len:
    sent = fd_socket.send(send_data[total_send:])
    if sent == 0:
     print "close socket"
     epoll.unregister(fd)
     fd_to_socket[fd].close()
     del fd_to_socket[fd]
     break
    else:
     print repr(send_data[total_send:])
     total_send = total_send + sent

其实这里的异常处理我们也可以用


except IOError as e:
 print e.errno
 print e.strerror

来源:https://blog.csdn.net/peng314899581/article/details/78066087

标签:python,epoll,服务端
0
投稿

猜你喜欢

  • 基于python判断字符串括号是否闭合{}[]()

    2022-03-25 15:58:45
  • js选取多个或单个元素的实现代码(用class)

    2023-08-24 16:51:29
  • Python3 类型标注支持操作

    2021-12-25 05:39:41
  • python爬取指定微信公众号文章

    2021-03-29 02:34:39
  • 宝塔面板成功部署Django项目流程(图文)

    2022-07-29 13:11:19
  • 解决Python复杂zip文件的解压问题

    2021-08-11 05:04:09
  • 把你的数据库置于版本控制之下

    2009-04-25 10:01:00
  • Python映射类型之dict详解

    2023-08-03 13:19:19
  • 详解Django中间件的5种自定义方法

    2022-07-24 03:51:43
  • python 筛选数据集中列中value长度大于20的数据集方法

    2023-05-27 03:55:02
  • python基本算法之实现归并排序(Merge sort)

    2023-04-06 03:20:07
  • 利用python Pandas实现批量拆分Excel与合并Excel

    2023-07-02 19:08:23
  • 在ASP处理程序时,进度显示

    2008-08-04 13:27:00
  • 在Django框架中自定义模板过滤器的方法

    2021-02-11 20:14:49
  • javascript与jsp发送请求到servlet的几种方式实例

    2023-06-15 15:59:30
  • python一行输入n个数据问题

    2023-09-11 21:50:48
  • 改进SQL Server数据库系统安全五步走

    2009-01-20 11:47:00
  • 详解Python 多线程 Timer定时器/延迟执行、Event事件

    2022-09-04 11:12:52
  • OpenCV图像分割之分水岭算法与图像金字塔算法详解

    2022-11-27 07:59:24
  • python自带的http模块详解

    2021-11-03 08:59:22
  • asp之家 网络编程 m.aspxhome.com