Python篇-Socket网络编程

作者: TianTianBaby223 | 来源:发表于2017-11-14 15:56 被阅读89次

    TZ:多读英文,少点烦躁

    一 : 科普一分钟

    简单来说Socket就是对TCP/IP等网络协议的封装和应用,其重要的两个动作就是发送接受当我们需要调用网络连接时只需建立Socket连接,Socket需要知道目标计算机的IP地址端口号,再指定协议类型即可。

    二: Socket创建客户端与服务端

    • 客户端

    1.导入socket模块

    import  socket
    

    2.创建实体类,发送数据,端口号的作用是连接后具体指定哪个程序响应

    #声明 socket 类型,同时生成socket连接对象
    client = socket.socket() 
    #连接ip地址和端口号
    client.connect(('www.TianTianbaby.com',9999))
    while True:
        mes = input(">> :").strip()
        if len(mes) == 0:
            continue
        if mes == 'q':
            break
    #客户端发送数据
        client.send(mes.encode())
    
    #客户端接收服务端返回的数据
        data = client.recv(1024)
    
    #打印返回信息
        print("recv:",data.decode())
    
    client.close()
    
    • 服务端

    1.导入socket模块

    import  socket,os
    

    2.创建实体类接收数据

    server = socket.socket()
    #绑定要监听的端口
    server.bind(('www.TianTianbaby.com',9999)) 
    #监听,参数为最大监听数量
    server.listen(5)
    print("等待ing")
    
    while True:
        #conn就是客户端连过来而在服务器端为其生成的一个连接实例
        conn, addr = server.accept()  
    
        while True:
    
           #接收数据,参数最大为 1024*8
            data = conn.recv(1024)
            print("Severrecv:",data)
    
           #客户端断开
            if not data:
                print("client has lost")
                break
    
           #把执行的数据返回给客户端
            res = os.popen(data).read()
            conn.send(res)
    server.close()
    

    三:Socket粘包

    • 产生原因:

    1.发送端需要等本机的缓冲区满了以后才发送出去,造成粘包(发送数据时间间隔很端,数据很小,会合在一个起,产生粘包)

    2.接收端不及时接收缓冲区的包,造成多个包接受(客户端发送一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据 ,就产生粘包)

    • 解决办法: 介绍两个比较简单的方法
      1.sleep 让上一次缓冲区超时.不等下一条.(不建议用)
      缺点:造成速度延迟
              conn.send(str(len(cmd_res.encode())).encode())
              time.sleep(0.5)
              conn.send(cmd_res.encode())
    

    2.插入交互 : 插入一个接受响应,如果不响应,第一个发送就不会等待.解决了粘包问题

            conn.send(str(len(cmd_res.encode())).encode())
            client_ack = conn.rec(1024)#等待确认
            conn.send(cmd_res.encode())
    

    另一端手动加一个响应:

        伪代码:上一次接收 client.recv(1024)
        # client.send("准备好接收了,可以发了".encode())
    
    

    四:SocketServer服务端

    SocketServer简化了网络服务器的编写。在进行socket创建时,使用SocketServer会大大减少创建的步骤.

    使用方法:

    • 创建服务器的步骤。首先,你必须创建一个请求处理类,它是BaseRequestHandler的子类并重载其handle()方法。

    • 实例化一个服务器类,传入服务器的地址和请求处理程序类。

    • 调用handle_request()(一般是调用其他事件循环或者使用select())或serve_forever()。

    继承关系:

    +------------+
            | BaseServer |
            +------------+
                  |
                  v
            +-----------+        +------------------+
            | TCPServer |------->| UnixStreamServer |
            +-----------+        +------------------+
                  |
                  v
            +-----------+        +--------------------+
            | UDPServer |------->| UnixDatagramServer |
            +-----------+        +--------------------+
    

    代码步骤:

    1导入模块SocketServer

    import  socketserver
    

    2.创建类

    class MyTCPHandler(socketserver.BaseRequestHandler):
    
    #与客户端所有的交互在handle完成
        def handle(self):
            while True:
                try:
                   #接收客户端数据
                    self.data = self.request.recv(1024).strip()
                    print("ip",self.client_address[0])
                    print(self.data)
    
                    # 如果客户端断开
                    if not self.data:
                        print(self.client_address, "断开了")
                        break
                   
                    #给客户端发送数据
                    self.request.sendall(self.data.upper())
         
               #如果客户端断开了
                except ConnectionResetError as e:
                    print("err",e)
                    break
    

    3.创建实例

    if __name__ == "__main__":
        HOST,PORT = 'www.TianTianbaby.com',9999
        server = 
    
    #创建一个多并发的服务
    socketserver.ThreadingTCPServer((HOST,PORT),MyTCPHandler)
    #永久打开
        server.serve_forever()
    

    五:总结

    数据链路层上识别mac(物理)地址,在网络层识别ip地址,而在传输层基于一些基本的协议如TCP/IP,'UDP'建立连接发送消息.
    TCP/IP要建立三次握手,四次接受,上学时候学习网络时候都有学习.
    既然是建立的连接,就要发送和接受消息,所以侧重点就是发和收,每个协议都要自己去实现发和收.比较繁琐麻烦.
    简单来说socket就是简化那么复杂的东西,封装给我们一个可以建立连接的模块方便我们使用.
    在使用socket的时候 我们只关心如何收和发就好了,编写出更高效的程序

    附:在评论处留下邮箱地址即可获得全注释源码

    相关文章

      网友评论

        本文标题:Python篇-Socket网络编程

        本文链接:https://www.haomeiwen.com/subject/ygzxvxtx.html