• Python 多线程套接字socketserver网络编程


    为什么使用socketserver

    虽然Python内置的socket和threading模块能实现简单的多线程服务器,在非正式环境,随便用用还是可以的,但是如果要在生产环境中使用,那是万万不够的。

    Python考虑得很周到,为了满足我们对多线程网络服务器的需求,提供了"socketserver"模块。socketserver在内部使用IO多路复用以及多线程/进程机制,实现了并发处理多个客户端请求的socket服务端。每个客户端请求连接到服务器时,socketserver服务端都会创建一个“线程”或者“进程” 专门负责处理当前客户端的所有请求。

    使用socketserver要点

    • 创建一个server类,继承"socketserver.BaseRequestHandler";
    • 这个类中必须重写一个名字为"handle"的方法,不能是别的名字,在此进行业务逻辑处理(比如收发数据等);
    • 将这个新建的类,连同服务器的IP和端口作为参数传递给"ThreadingTCPServer()"实例化;
    • 启动"ThreadingTCPServerObj.serve_forever()"。

    栗子

    服务端

    import socketserver
    
    
    # 1.必须继承socketserver.BaseRequestHandler类,后台自动建立双工通信,等待客户端连接
    class MySockServer(socketserver.BaseRequestHandler):
        def handle(self):
         # 2.进行收发数据
    # request对象进行接收和发送数据 request = self.request request.send('欢迎访问socketserver服务器'.encode())  # 发送数据send() while True: data = request.recv(1024).decode()          # 接收数据recv() if data == 'exit': print('断开与%s的连接!' % (self.client_address,)) break elif data: print('来自%s客户端向你发来数据:%s' % (self.client_address, data)) request.send('服务器已收到数据'.encode())   # 发送数据 if __name__ == '__main__': # 3.创建一个多线程TCP服务器对象,绑定IP和端口 tcp_server = socketserver.ThreadingTCPServer(('127.0.0.1', 8888), MySockServer) print('启动服务器!') # 4.启动服务器,服务器将一直保持运行状态 tcp_server.serve_forever()

    分析一下服务器端的代码,核心要点有这些:

    • 连接数据封装在"self.request"属性中!通过"self.request"对象调用"send()"和"recv()"方法。
    • "handle()"方法是整个通信的处理核心(业务逻辑处理,如收发数据等),一旦它运行结束,当前连接也就断开了(但其他的线程和客户端还正常),因此一般在此设置一个无限循环。
    • 注意"sock_server = socketserver.ThreadingTCPServer(('127.0.0.1', 8888), MySockServer)"中参数传递的方法。
    • "sock_server.serve_forever()"表示该服务器在正常情况下将永远运行。

    客户端

    import socket
    
    # 客户端依然使用socket模块就可以了,不需要导入socketserver模块
    
    IP_PORT = ('127.0.0.1', 8888)
    # 1.创建socket对象
    sock
    = socket.socket()
    # 2.与服务端连接,建立双工通信 sock.connect(IP_PORT) sock.settimeout(
    0.5)
    # 3.进行收发数据 data
    = sock.recv(1024).decode()    # 接收数据recv() print('接收返回数据:%s' % data) while True: inp = input('输入要发送的数据:').strip() if not inp: continue sock.send(inp.encode())    # 发送数据send() if inp == 'exit': print('谢谢使用,再见!') break data = sock.recv(1024).decode() print('接收返回数据:%s' % data)
    # 4.断开连接 sock.close()

    客户端的代码很好理解,依然使用socket模块就可以了,不需要导入socketserver模块。

      至此,转载请注明出处。

  • 相关阅读:
    转:高并发高负载系统架构
    用java模拟银行柜台排队
    转:VS2010与SVN
    转:MySQL导入.sql文件及常用命令
    转:Mongodb中随机的查询文档记录
    转:Thumbs.db是什么文件?是病毒吗?怎么处理?
    转:OWASP发布Web应用程序的十大安全风险
    转:Top 10 Algorithms for Coding Interview
    编写C# Windows服务,用于杀死Zsd.exe进程
    转:eclipse载入extjs4出现内存溢出错误的解决方法
  • 原文地址:https://www.cnblogs.com/wcwnina/p/8893693.html
Copyright © 2020-2023  润新知