python 网络编程学习 非阻塞socket

本文介绍了Python中使用SocketServer进行网络编程,包括同步和异步处理,特别是结合ThreadingMixIn和ForkingMixIn实现异步服务器。强调了在处理大量并发连接时,使用select模块(如select、poll、epoll)的重要性,并以一个聊天室服务器和简单的web服务器为例,展示了I/O多路复用的概念。
摘要由CSDN通过智能技术生成

主要学习服务器的异步使用

SocketServer简化了网络服务器的编写。它有4个类:TCPServer,UDPServer,UnixStreamServer,UnixDatagramServer。这4个类是同步进行处理的,另外通过ForkingMixIn和ThreadingMixIn类来支持异步。

创建服务器的步骤

  1. 创建一个请求处理类,它是BaseRequestHandler的子类并重载其handle()方法。
  2. 实例化一个服务器类,传入服务器的地址和请求处理程序类。
  3. 调用handle_request()(一般是调用其他事件循环或者使用select())或serve_forever()。

集成ThreadingMixIn类时需要处理异常关闭。daemon_threads指示服务器是否要等待线程终止,要是线程互相独立,必须要设置为True,默认是False。


使用基于多进程,ForkingMinIn 支持异步

import os                                                                                                                                                                          
import socket                                                                       
import threading                                                                    
import SocketServer                                                                 
                                                                                    
# 构造客户端                                                                               
class ForkingClient():                                                              
    def __init__(self, ip, port):                                                   
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)     
        self.sock.connect((ip, port))                                               
                                                                                    
    def run(self):                                                                  
        crtpid = os.getpid()                                                        
        print "PID: %s " % crtpid                                                    
        send_length = self.sock.send("hello, world!")                               
        print "sent %d characters..." % send_length                                 
        res = self.sock.recv(2048)                                                  
        print "PID %s received: %s" % (crtpid, res)                                 
                                                                                    
    def shutdown(self):                                                             
        self.sock.close()                                                           
                                                                                    
# 写服务端处理函数                                                                                
class ForkingServerRequestHandler(SocketServer.BaseRequestHandler):                 
    def handle(self):                                                               
        data = self.request.recv(2048)                                              
        crtpid = os.getpid()                                                        
        res = "%s: %s" % (crtpid, data)                                             
        print res                                                                   
        self.request.send(res)                                                      
        return                                                                      
                                                                                    
# 继承                                                                                  
class ForkingServer(SocketServer.ForkingMixIn, SocketServer.TCPServer):             
    pass                                                                            
                                                                                    
                                                                                    
def main():                                                                         
    server = ForkingServer(('localhost', 8989), ForkingServerRequestHandler)        
    ip, port = server.server_address                                                
    server_thread = threading.Thread(target=server.serve_forever)                   
    server_thread.setDaemon(True)                                                   
    server_thread.start()
    print 'Server loop running PID: %s' % os.getpid()

    client_1 = ForkingClient(ip, port)
    client_2 = ForkingClient(ip, port)

    client_1.run()
    client_2.run()
                                                                                    
    client_1.shutdown()
    client_2.shutdown()
    server.socket.close()

                                                                          
if __name__ == '__main__':
    main()
 

执行可以看到

duck@duck:~/sockdir/chapter_2$ python forkser.py 
Server loop running PID: 22649
PID: %s  22649
sent 13 characters...
22651: hello, world!
PID 22649 received: 22651: hello, world!
PID: %s  22649
sent 13 characters...
22652: hello, world!
PID 22649 received: 22652: hello, world!

现在用ThreadingMixIn

优势:线程之间共享应用状态容易,避免进程间通信

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值