zoukankan      html  css  js  c++  java
  • 【Python】socket编程-3

    1、      SocketServer最简单的使用方法:
    
    (1)        创建一个Handler类,继承自BaseRequestHandler,重写其handle(),在该方法中完成对请求的处理。
    
    (2)        实例化一个Server类对象(根据不同的server类型选择不同的Server类)。并将IP、端口和Handler类传递给Server的构造函数。
    
    (3)        调用server对象的server_forever()开启服务。
    
    2、      Socket.server提供的类类型
    
    (1)   socketserver中类分为三种类型。一是Server类:BaseServer/TCPServer/UDPServer用来接收客户的请求。TCPServer处理TCP请求,UDPServer处理UDP请求。BaserServer是基类,不能直接使用。TCPServer继承自BaseServer,UDPServer继承自TCPServer。暂时不明白为什么UDPServer要继承自TCPServer,后面再说。
    
    (2)   二是Handler类:BaseRequestHandler/DatagramRequestHandler/StreamRequestHandler用来处理每一个客户请求。一般用使用BaseRequestHandler就行,但StreamRequestHandler/DatagramRequestHandler提供了一些特别的功能,前者用来处理流式(TCP)请求,后者处理数据报(UDP)请求。Server每收到一个客户请求就会创建一个Handler类示例来处理该请求。默认情况下,TCPServer/UDPServer是单进程单线程的模型,依次处理每个客户请求,一个请求处理完毕才能接着处理下一个请求。
    
    (3)   三是MixIn类:ForkingMixIn/ThreadingMixIn用来为Server提供多进程/多线程并发处理能力的。ForkingMixIn是多进程模型,ThreadingMixin是多线程模型。这里特别巧妙的是,你只要创建一个类,同时继承Server类和MixIn类就能自动获得并发处理请求的能力。该模块本身就直接提供了这种类。
    
    3、      ThreadingTCPServer/TCPServer/ForkingTCPServer的区别:
    
    这三个类其实就是对接收到request请求后的不同处理方法。
    
    TCPServer是接收到请求后执行handle方法,如果前一个的handle没有结束,那么其他的请求将不会受理,新的客户端也无法加入。
    
    而ThreadingTCPServer和ForkingTCPServer则允许前一连接的handle未结束也可受理新的请求和连接新的客户端,区别在于前者用建立新线程的方法运行handle,后者用新进程的方法运行handle。
    
    
    
    #练习9:SocketServer
    服务端:
    import SocketServer
    import threading
    
    class MyTCPHandler(SocketServer.BaseRequestHandler):
        def handle(self):
            while True:
                self.data = self.request.recv(1024).strip()
                cur_thread = threading.current_thread()
                print cur_thread
                if not self.data:
                    print u"客户端:%s 退出!" % self.client_address[0]
                    break
                print u"%s 内容:%s" % (self.client_address[0], self.data)
                self.request.sendall(self.data.upper())
    
    if __name__ == "__main__":
        HOST, PORT = "47.98.155.208", 8001
        server = SocketServer.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
        server.serve_forever()
    
    客户端:
    if __name__=="__main__":
        import socket
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        socket.connect(("'47.98.155.208', 8001"))
        import time
        time.sleep(2)
        socket.send("ls -al /home/WANGJING"+"
    ")
        print socket.recv(1024).deconde("gbk")
    socket.close()
    
    
    fd:file descriptor 文件描述符
    
    fd_r_list, fd_w_list, fd_x_list = select.select(rlist, wlist, xlist, [timeout])
    
    参数: 可接受四个参数(前三个必须)
    
    rlist: wait until ready for reading
    
    wlist: wait until ready for writing(一般不使用)
    
    xlist: wait for an “exceptional condition”
    
    timeout: 超时时间
    
    
    
    #练习10:select 单线程实现多线程效果
    服务端:
    import socket
    import select
    
    s = socket.socket()
    s.bind(('127.0.0.1', 8888))
    s.listen(5)
    r_list = [s, ]
    num = 0
    while True:
        print u"开始进入监听状态..."
        rl, wl, error = select.select(r_list, [], [], 10)
        # 第一次执行循环体:客户端建立的连接的时候,rl和r_list分别是[s,]和[s,]
        #                  执行连接之后,r_list变为了[s,conn]
        # 第二次执行循环体:rl和r_list分别是[conn,]和[s,conn],执行else逻辑
        #
        #第n次执行循环体:rl和r_list分别是[conn,]和[s,conn],执行else逻辑
    
        num += 1
        print u'执行次数%s'% num
        print("rl's length is %s" % len(rl))
        print("r_list length %s" % len(r_list))
        print "--------------length:", len(rl)
        print [i for i in rl]
        for fd in rl:
            if fd == s:
                conn, addr = fd.accept()
                r_list.append(conn)
                msg = conn.recv(200)
                conn.sendall(('first----%s' % conn.fileno()).encode("gbk"))
            else:
                try:
                    msg = fd.recv(200)
                    fd.sendall('second'.encode())
                except ConnectionAbortedError:
                    r_list.remove(fd)
    s.close()
    
    客户端:
    import socket
    flag = 1
    s = socket.socket()
    s.connect(('127.0.0.1', 8888))
    while flag:
        input_msg = raw_input('input>>>')
        if input_msg == '0':
            break
        s.sendall(input_msg.encode())
        msg = s.recv(1024)
        print(msg.decode())
    s.close()
  • 相关阅读:
    响应式布局
    bootstrap--前端开发框架
    ADO.NET Entity Framework
    dns
    自动完成脚本
    一个Banner广告收缩效果
    对联广告2
    蓝色经典的对联广告代码
    Js弹性漂浮广告代码
    jquery悬停tab2
  • 原文地址:https://www.cnblogs.com/jingsheng99/p/9006453.html
Copyright © 2011-2022 走看看