zoukankan      html  css  js  c++  java
  • python中的sockeserver模块简单实用

    1、 socketserver模块简介


    在python的socket编程中,实用socket模块的时候,是不能实现多个连接的,当然如果加入其它的模块是可以的,例如select模块,在这里见到的介绍下socketserver模块。


    socketserver,看其名字,就知道是一个socket的服务器模块的使用,在这个模块中,主要也就是实现服务器类的相关功能,在其中,也就是将socket模块和select模块进行了封装,从而创建了一些基类供人使用。


    2、 socketserver服务器端和客户端代码

    在socketserver模块中,主要就是使用一些服务器类,从而简化socket网络编程的方法,先上一段基本的服务器代码:

    #!/usr/bin/env python
    
    import SocketServer
    import time
    
    
    HOST = '192.168.1.60'
    PORT = 9999
    
    class MyHandler(SocketServer.BaseRequestHandler):
        def handle(self):
            while True:
                data = self.request.recv(1024)
                print data,self.client_address
                self.request.send( ' %s %s ' % (data,time.ctime()))
                if data == 'exit':
                    break
    
    s = SocketServer.ThreadingTCPServer((HOST,PORT),MyHandler)
    s.serve_forever()

    在上述的代码中,仅仅做了几件事,先定义了一个类,也就是处理请求的类,从基类baserequesthandler继承,主要就是重写其中handle方法,告知服务器如何来处理客户端的请求。

    然后创建了一个线程的TCP服务器类,也就是通过多线程来进行应答客户端,然后使用一直运行的方法也就是serve_forever。


    客户端代码如下:

    #!/usr/bin/env python
    
    import socket
    
    HOST = '192.168.1.60'
    PORT = 9999
    
    s = socket.socket()
    s.connect((HOST,PORT))
    while True:
        kel = raw_input('>>>')
        s.sendall(kel)
        print s.recv(1024)
        if kel == 'exit':
            break
    s.close()
    客户端的代码和socket编程的代码基本相同,因为在socketserver模块中,主要是创建socke的服务端,而不涉及到客户端,从而客户端不需要修改代码即可进行运行。


    对比此段代码和socket编程的区别是:可以和多个client端同时进行通信。

    [root@python 514]# ps -ef|grep python
    root      8628  6091  0 12:56 pts/3    00:00:00 python server.py
    root      8629 32625  0 12:56 pts/0    00:00:00 python client.py
    root      8656  8634  0 12:56 pts/1    00:00:00 python client.py

    在单纯的socket编码中,同时只能一个进行通信,其他的连接会被阻塞。


    3、 socketserver模块类介绍

    在socketserver的默认请求处理器中,是接收连接,得到请求,然后就关闭连接,从而也就是客户端在循环的时候,必须每次都进行重新连接。

    在上面的代码中,重写了事件处理的方法handle,在其中使用了循环,也就是一直保持和客户端的连接。


    请求处理的基类是BaseRequestHandler,其中一般需要重写的方法就是handle方法,主要就是如何处理接下来的请求,在这个类里,主要有三个方法,一个是setup,handle和finish方法,在调用这个类的时候,先调用setup进行一些初始化的工作,然后调用handle方法进行处理请求,然后调用finish方法,做一些关闭连接什么的;在这个里面最主要的参数self.request,也就是请求的socket对象,其中可以发送消息sendall或者send,接收消息的recv

    在请求处理的子类中有两个,一个是SreamRequestHandle和DatagramRequestHandle,在这个里面重写了基类的setup方法和finish方法,handle方法没有重写,因为这个是留给用户做处理请求的方法,在这里提供了几个参数,一个self.rfile用来读取数据的句柄,而self.wfile是用来发送消息的句柄。

    在使用rfile和wfile时候需要注意,在客户端发送消息的时候需要自己加上回车,而在服务器端需要使用readline方法来进行读取,也就是读取一行,如下所示服务器端代码:

    #!/usr/bin/env python
    
    import SocketServer
    import time
    
    
    HOST = '192.168.1.60'
    PORT = 9999
    
    class MyHandler(SocketServer.StreamRequestHandler):
        def handle(self):
            while True:
                data = self.rfile.readline().strip()
                print data,self.client_address
                self.wfile.write( ' %s %s ' % (data,time.ctime()))
                if data == 'exit':
                    break
    
    s = SocketServer.ThreadingTCPServer((HOST,PORT),MyHandler)
    s.serve_forever()
    在使用rfile的时候,需要使用readline方法,否则会卡住请求的处理,而在客户端代码如下:

    #!/usr/bin/env python
    
    import socket
    
    HOST = '192.168.1.60'
    PORT = 9999
    
    s = socket.socket()
    s.connect((HOST,PORT))
    while True:
    #    s = socket.socket()
    #    s.connect((HOST,PORT))
        kel = raw_input('>>>')
        s.sendall(kel + '
    ')
        print s.recv(1024)
        if kel == 'exit':
            break
    s.close()
    在进行sendall数据的时候,需要加上'' ',表示此次发送的数据结束。


    最基类的是服务器类BaseServer类,其中定义了相关的方法,不能直接使用这个类,只能用来继承,在子类中有俩,是作为同步服务器类使用,TCPServer和UDPServer,这两个类主要是和socket编程的时候是相同的,也就是会阻塞连接。TCPServer有一个子类为UNIXStreamServer,在UDPServer有一个子类为UnixDatagramServer,在最后的两个子类中,是基于文件同步的tcp和udp服务器。


    两个混合类,一个是ForkingMixin,主要是用fork的,产生一个新的进程去处理;一个是ThreadingMixin,产生一个新的线程,主要是用来提供异步处理的能力,其余tcpserver和udpserver组合,又产生了新的四个类,从而提供异步处理的能力。


    在使用混合类和服务器类的时候,注意混合类需要写在前面,因为混合类重写了服务器类的方法,从而需要放在第一个位置。


    总结:

    python中的socketserver模块,主要是用来提供服务器类,并且提供异步处理的能力。







  • 相关阅读:
    linux的redis的安装和使用
    在linux上安装Mysql和使用
    linux的python3的安装
    linux的优化和命令
    LeetCode 542. 01 Matrix
    Qt keyPressEvent
    QOpenGLTexture 两个纹理叠加
    Qt5.6.0+OpenGL 纹理贴图首战告捷
    更改Qt Application为 Qt Console Application
    Learning part-based templates from large collections of 3D shapse CorrsTmplt Kim 代码调试
  • 原文地址:https://www.cnblogs.com/kellyseeme/p/5525023.html
Copyright © 2011-2022 走看看