zoukankan      html  css  js  c++  java
  • Python-socket通信

    一、基于udp协议的套接子通信

    TCP协议与UDP协议的比较

    可靠性

    tcp协议是可靠协议:
    对方必须回复一个ack确认信息,才会将自己这端的数据从内存中删除

    udp协议不可靠:
    发送一条消息就会立即删除,不管对方是否接收到

    有无链接

    tcp有链接,udp无链接

    传输数据的效率

    udp更高,因为udp不需要建立链接,没有三次握手四次挥手的等待时间

    粘包问题

    udp协议称之为数据报协议,每次发送都是一个完整的数据报,一个发送唯一对应一个接收
    所以udp协议没有粘包问题

    套接字通信

    服务端

    对比tcp协议的通信,udp少了设置listen的前置要求,同时对于通信时,也没有accep的接受,而是直接在接受的信息里获取客户端的ip与端口

    from socket import *
    import time
    
    server = socket(AF_INET, SOCK_DGRAM)
    server.bind(('127.0.0.1', 8080))
    
    while True:
        data, client_addr = server.recvfrom(1024)
        time.sleep(10)
        server.sendto(data.upper(), client_addr)
    

    客户端

    客户端的改动并不大,改动内容仅仅为去掉了链接的语句,因为udp本身并不建立链接,也就不存在连接的情况了,我们连接的ip与端口直接与内容一起发送。

    from socket import *
    
    client = socket(AF_INET, SOCK_DGRAM)
    
    while True:
        msg = input('>>: ').strip()
        client.sendto(msg.encode("utf-8"), ('127.0.0.1', 8080))
    
        data, server_addr = client.recvfrom(1024)
        print(data.decode('utf-8'))
    

    二、基于socketserver模块实现并发TCP

    服务端

    利用对象的思想,首先我们自定义一个类,但是必须继承socketserver.BaseRequestHandler,同时,类中必须实现handle方法,其中编写我们处理通信的代码。我们接受的到的内容,在之前都是用conn来接受信息,现在由对象的request属性来接收。

    我们通信有接收通信与处理通信两步,ThreadingTCPServer是对接收到request请求后的处理方法,允许前一连接的handle未结束也可受理新的请求和连接新的客户端,并且建立新线程的方法运行handle。在其中需要表明本地的ip与端口,并将自定义类名写进去,最后的bind_and_activate=True是默认的可不填写,如果为True,将自动调用server_bind()和server_activate()。

    与之对应的是ForkingTCPServer,同样允许前一连接的handle未结束也可受理新的请求和连接新的客户端,但是用新进程的方法运行handle。

    import socketserver
    
    class MyRequestHandler(socketserver.BaseRequestHandler):
        def handle(self):  # 处理通信
            print(self.client_address)
            while True:
                try:
                    data = self.request.recv(1024)  # self.request=>conn
                    if len(data) == 0: break
                    self.request.send(data.upper())
                except Exception:
                    break
            self.request.close()
    
    
    if __name__ == '__main__':
        s = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyRequestHandler, bind_and_activate=True)
        s.serve_forever()
    

    客户端

    from socket import *
    
    client=socket(AF_INET,SOCK_STREAM)
    client.connect(('127.0.0.1',8080))
    
    while True:
        msg=input(">>: ").strip()
        if len(msg) == 0:
            continue
    
        client.send(msg.encode('utf-8'))
        data=client.recv(1024)
        print(data.decode('utf-8'))
    

    三、基于socketserver模块实现并发UDP

    服务端

    相比于tcp协议,udp协议减少了异常处理

    import socketserver
    
    
    class MyRequestHandler(socketserver.BaseRequestHandler):
        def handle(self):  # 处理通信
            data,server=self.request
            server.sendto(data.upper(),self.client_address)
    
    if __name__ == '__main__':
        s = socketserver.ThreadingUDPServer(('127.0.0.1', 8080), MyRequestHandler, bind_and_activate=True)
        s.serve_forever()
    
    

    客户端

    from socket import *
    
    client = socket(AF_INET, SOCK_DGRAM)
    
    while True:
        msg = input('>>: ').strip()
        client.sendto(msg.encode("utf-8"), ('127.0.0.1', 8080))
    
        data, server_addr = client.recvfrom(1024)
        print(data.decode('utf-8'))
    
    
  • 相关阅读:
    《安富莱嵌入式周报》第241期:2021.11.222021.11.28
    开源功率计,带电源功能,专用于物联网功耗测量
    实用技能分享,充分利用内联函数,内联汇编,内部函数和嵌入式汇编提升代码执行效率和便捷性(20211217)
    【STM32F407】第7章 RTX5任务管理
    【STM32H7】第8章 RTX5任务优先级分配和修改
    H7TOOL的LUA小程序教程第3期:使用LUA控制H7TOOL的LCD简易界面设计
    【小知识】使用串口8bit,7bit和6bit数据格式的奇偶校验问题
    【第3版emWin教程】第53章 emWin6.x的按钮Button控件
    【第3版emWin教程】第51章 emWin6.x的Window窗口控件
    各种GUIBuilder体验TouchGFX,AppWizard,GUIX Studio,Embedded Wizard,AWTK,柿饼UI,LVGL,Qt fot MCU等(20211221)
  • 原文地址:https://www.cnblogs.com/chiyun/p/14066335.html
Copyright © 2011-2022 走看看