socketserver模块解析

2019-06-11  本文已影响0人  王裕杰

socketserver模块是基于socket而来的模块,它是在socket的基础上进行了一层封装,并且实现并发等功能。

看看具体用法:

import socketserver                              #1、引入模块
class MyServer(socketserver.BaseRequestHandler): #2、自己写一个类,类名自己随便定义,然后继承socketserver这个模块里面的BaseRequestHandler这个类

    def handle(self):                            #3、写一个handle方法,必须叫这个名字
        #self.request                            #6、self.request 相当于一个conn

        self.request.recv(1024)                  #7、收消息
        msg = '亲,学会了吗'
        self.request.send(bytes(msg,encoding='utf-8')) #8、发消息

        self.request.close()                     #9、关闭连接

        # 拿到了我们对每个客户端的管道,那么我们自己在这个方法里面的就写我们接收消息发送消息的逻辑就可以了
        pass
if __name__ == '__mian__':
    #thread 线程,现在只需要简单理解线程,别着急,后面很快就会讲到啦,看下面的图
    server = socketserver.ThreadingTCPServer(('127.0.0.1',8090),MyServer)#4、使用socketserver的ThreadingTCPServer这个类,将IP和端口的元祖传进去,还需要将上面咱们自己定义的类传进去,得到一个对象,相当于我们通过它进行了bind、listen
    server.serve_forever()                       #5、使用我们上面这个类的对象来执行serve_forever()方法,他的作用就是说,我的服务一直开启着,就像京东一样,不能关闭网站,对吧,并且serve_forever()帮我们进行了accept


#注意:
#有socketserver 那么有socketclient的吗?
#当然不会有,我要作为客户去访问京东的时候,京东帮我也客户端了吗,客户端是不是在我们自己的电脑啊,并且socketserver对客户端没有太高的要求,只需要自己写一些socket就行了。
截图

通过上面的代码,我们来分析socket的源码:

在整个socketserver这个模块中,其实就干了两件事情:

1、一个是循环建立链接的部分,每个客户链接都可以连接成功

2、一个通讯循环的部分,就是每个客户端链接成功之后,要循环的和客户端进行通信。

看代码中的:server=socketserver.ThreadingTCPServer(('127.0.0.1',8090),MyServer)

还记得面向对象的继承吗?来,大家自己尝试着看看源码:

查找属性的顺序:ThreadingTCPServer->ThreadingMixIn->TCPServer->BaseServer

实例化得到server,先找ThreadMinxIn中的__init__方法,发现没有init方法,然后找类ThreadingTCPServer__init__,在TCPServer中找到,在里面创建了socket对象,进而执行server_bind(相当于bind),server_active(点进去看执行了listen
server下的serve_forever,在BaseServer中找到,进而执行self._handle_request_noblock(),该方法同样是在BaseServer
执行self._handle_request_noblock()进而执行request, client_address = self.get_request()(就是TCPServer中的self.socket.accept()),然后执行self.process_request(request, client_address)

ThreadingMixIn中找到process_request,开启多线程应对并发,进而执行process_request_thread,执行self.finish_request(request, client_address)

上述四部分完成了链接循环,本部分开始进入处理通讯部分,在BaseServer中找到finish_request,触发我们自己定义的类的实例化,去找__init__方法,而我们自己定义的类没有该方法,则去它的父类也就是BaseRequestHandler中找....

源码分析总结:

基于tcp的socketserver我们自己定义的类中的

基于udp的socketserver我们自己定义的类中的

一个完整的sockeserver代码示例:

服务端代码示例:


import socketserver

class MysocketServer(socketserver.BaseRequestHandler):
    def handle(self):
        # self.request  相当于conn链接通道
        while 1:
            from_client_msg = self.request.recv(1024)
            print(from_client_msg.decode("utf-8"))
            server_msg = input("服务器>>>")
            self.request.send(server_msg.encode("utf-8"))


if __name__ == '__main__':
    ip_port = ('127.0.0.1', 8001)
    server = socketserver.ThreadingTCPServer(ip_port, MysocketServer)
    server.serve_forever()

client.py


import socket

client=socket.socket()
client.connect(('127.0.0.1',8001))

while 1:
    msg=input('别开车>>>').encode("utf-8")
    client.send(msg)

    from_server_msg=client.recv(1024)
    print(from_server_msg.decode("utf-8"))

client.close()
上一篇下一篇

猜你喜欢

热点阅读