• python-socket并发-解决tcp粘包问题


    粘包问题

    tcp协议才会有粘包问题,udp协议没有粘包问题.

    因为tcp协议是将需要传输的内容先读入缓存里,然后在一点点传,受接收方字符限制,并不能一次传输完成,第二次就会将第一次剩下的部分+第二次的内容传输

    而udp协议,是如果接收方一次性没有接收完全,剩下数据将被丢弃.

    粘包问题的几种情况

    1. 两个数据非常小,间隔时间又短
    2. 数据太大,一次取不完,下一次还会取这个大数据

    解决粘包问题

    在传数据之前,传一个数据的大小,数据的大小必须得定长

    基于udp协议的socket套接字编程

    udp无需连接

    • 服务端
    import socket
    
    server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    server.bind(('127.0.0.1', 8000))
    
    print('start...')
    while True:
        data, client_addr = server.recvfrom(1024)
        print(client_addr)
        print(data)
        server.sendto(data.upper(), client_addr)
    
    
    • 客户端
    import socket
    
    client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    while True:
        msg = input('please enter your msg:')
        client.sendto(msg.encode('utf8'), ('127.0.0.1', 8000))
    
        data = client.recvfrom(1024)
        print(data)
    
    

    基于socketserver实现并发的socket套接字编程

    让服务端同时和多个客户端进行连接交互

    • 服务端
    # 同一时刻有多个人在接听
    import socketserver
    import subprocess
    import struct
    
    
    class MyHandler(socketserver.BaseRequestHandler):
        # 通信循环
        def handle(self):
    
            while True:
                try:
                    cmd = self.request.recv(1024)
                    print(cmd)
    
                    pipeline = subprocess.Popen(cmd.decode('utf8'),
                                                shell=True,
                                                stderr=subprocess.PIPE,
                                                stdout=subprocess.PIPE)
    
                    stdout = pipeline.stdout.read()
                    stderr = pipeline.stderr.read()
    
                    count_len = len(stdout) + len(stderr)
                    guding_bytes = struct.pack('i', count_len)
    
                    self.request.send(guding_bytes)  # 4
    
                    self.request.send(stderr + stdout)
    
                except ConnectionResetError:
                    break
    
    
    # 使用socketserver的连接循环(并发),但是使用了自己的通信循环
    # myhandler = MyHandler()
    if __name__ == '__main__':
        server = socketserver.ThreadingTCPServer(('127.0.0.1', 8000), MyHandler, bind_and_activate=True)
        print('start...')
        server.serve_forever()
    
  • 相关阅读:
    设计模式——迭代器模式
    FTP服务:FileZilla的配置和使用
    FTP服务:使用FileZilla搭建FTP服务
    FTP服务:ISS搭建服务
    javaweb项目使用RSA算法
    我在博客园的第一篇博客
    杰表打印跟乱码修改
    jsp页面角色判断
    test : 摘自 https://www.cnblogs.com/yyman001/p/3366764.html
    mybatis中sql查询不到数据单独运行sql可以获取数据
  • 原文地址:https://www.cnblogs.com/raynduan/p/11186851.html
Copyright © 2020-2023  润新知