• Python网络编程:Linux epoll


    原文地址:http://scotdoyle.com/python-epoll-howto.html

    介绍

    Python已于2.6版本添加访问Linux epoll库的API。这篇教程使用Python 3简要介绍如何使用Linux epoll。

    阻塞Socket

     例1是一个Pyhton服务端程序,它监听8080端口,接收HTTP请求并将其打印到console,然后对HTTP请求进行回复。

    #Example 1
    import socket EOL1 = b' ' EOL2 = b' ' response = b'HTTP/1.0 200 OK Date: Mon, 1 Jan 1996 01:01:01 GMT ' response += b'Content-Type: text/plain Content-Length: 13 ' response += b'Hello, world!' #创建socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) serversocket.bind(('0.0.0.0', 8080)) serversocket.listen(1) connectiontoclient, address = serversocket.accept() request = b'' while EOL1 not in request and EOL2 not in request: request += connectiontoclient.recv(1024) print(request.decode()) connectiontoclient.send(response) connectiontoclient.close() serversocket.close()

    下面的代码添加了一个循环,不断接收客户端的请求直到被我们手动关闭。例2更清楚地展示了服务端创建的socket不直接与客户端进行数据交换,而是服务端socket接收到来自客户端的连接后,创建一个新的socket与该客户端进行通信。

    #Example 2
    import socket
    
    EOL1 = b'
    
    '
    EOL2 = b'
    
    '
    response  = b'HTTP/1.0 200 OK
    Date: Mon, 1 Jan 1996 01:01:01 GMT
    '
    response += b'Content-Type: text/plain
    Content-Length: 13
    
    '
    response += b'Hello, world!'
    
    serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    serversocket.bind(('0.0.0.0', 8080))
    serversocket.listen(1)
    
    try:
        while True:
           connectiontoclient, address = serversocket.accept()
           request = b''
           while EOL1 not in request and EOL2 not in request:
               request += connectiontoclient.recv(1024)
           print('-'*40 + '
    ' + request.decode()[:-2])
           connectiontoclient.send(response)
           connectiontoclient.close()
    
    #确保程序即使出现exception,socket也会被关闭
    finally:
       serversocket.close()

    非阻塞Socket和Linux epoll的好处

    上面两个例子展示的都是阻塞socket。Python代码执行到某行会停在那里直到某一事件发生。如16行的accept()会被阻塞直到有一个客户端请求连接。19行的recv()会被阻塞直到客户端发送了数据(或没有数据可读取)。21行的send()会被阻塞直到所有要发送给客户端的数据已经Linux被放入了传输队列。

    当一个服务端程序使用阻塞socket时,对于每一个客户端,其经常使用一个线程甚至一个专门的进程进行通讯。服务端程序的主线程则主要包括监听的被用来接受客户端请求的socket。其每次接收一个来自客户端的请求,并把新创建的用于和客户端通信的socket传给另外一个线程与客户端进行交互。因为每个线程只与一个客户端进行通讯,某一个线程出现阻塞不会影响到其他线程执行的任务。

    使用多线程和阻塞socket进行网络编程写出的代码更加直观、简单,但是有不少缺点。多线程需要考虑到操作系统关于资源共享的常见问题,并且这种编程方式对单核CPU很不友好。

    The C10K Problem讨论了若干种处理并发连接的方法,比如使用异步socket。

  • 相关阅读:
    分解质因数算法
    js 的 Math 对象
    字符串操作
    简化求质数算法
    数值类型小数点后是否可以接零问题
    新博第一篇,思考的重要性与求质数算法
    一、制作屏幕录像
    四、同步线程
    常见问题
    jni数据处理
  • 原文地址:https://www.cnblogs.com/Antiver/p/9569406.html
Copyright © 2020-2023  润新知