zoukankan      html  css  js  c++  java
  • socket套接字

    socket套接字

    基于TCP协议的socket

    流式协议,面向流的通信是无消息保护边界的

    会将数据少、时间间隔短的数据一次性打包发送

    可靠但粘包:数据不会丢,包没收完,会继续上次继续接收数据。数据是可靠的

    只有TCP有粘包现象

     

    粘包问题

     

    产生原因:1.发送的数据小,时间段,TCP会议会自动合成数据,造成粘包。(发送方的缓存机制)。

          2.接收数据只接收一部分,下次接收会继续上次接收数据。(接收方的缓存机制)

    只发生在TCP协议。

    问题的根源:

    ​ 接收方不知道消息的大小

    解决方案:

    1.发送方提供数据大小

    2.利用struct模块调用.pack将长度打包header报头发送

    3.接收方利用struct调用.unpack解包header报头取出长度

    案例:利用subprocess模拟终端命令输入

    '''
    客户端                                     
    
    1、连接服务                                                                                            
    2、发送命令                                                                                           
    3、接收header报头                            
    4、struct.unpack header报头得到字典长度      
    5、利用字典长度接收字典                      
    6、拿出字典里面真实数据长度                    
    7、分段接收真实数据   
    '''                        
    '''
    服务端:
    
    1、开启服务                                                          
    2、接收客户端命令                                                          
    3、利用subprocess返回命令结果res
    4、构造res数据的字典
    5、序列化字典,得出序列化后的字典长度
    6、利用struct模块构造字典长度的header头
    7、发送header头
    8、发送字典
    9、发送真实数据
    '''

    client.py:

    import socket
    import struct
    import json
    
    
    IP = '127.0.0.1'
    PORT = 8001
    
    client = socket.socket()
    client.connect((IP, PORT))
    
    while True:
        cmd = input('>>>').strip()
        client.send(cmd.encode('utf-8'))
        # 接收字典报头
        data = client.recv(4)
        dict_size = struct.unpack('i', data)[0]
        # 接收字典数据
        dict_data = client.recv(dict_size)
        dic = json.loads(dict_data.decode('utf-8'))
        # 取出数据长度
        file_size = dic.get('file_size')
        #接收真实数据
        recv_size = 0
        real_data = b''
        while recv_size < file_size:
            data = client.recv(1024)
            real_data += data
            recv_size += len(data)
    
        print(real_data.decode('utf-8'))

    server.py

    import socket
    import subprocess
    import struct
    import json
    
    IP = '127.0.0.1'
    PORT = 8001
    
    server = socket.socket()
    server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    server.bind((IP, PORT))
    server.listen(5)
    
    while True:
        conn, addr = server.accept()
        while True:
            try:
                print('客户端地址:', addr)
                cmd = conn.recv(1024)
                obj = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                res = obj.stdout.read() + obj.stderr.read()
    
                # 构造一个字典
                dic = {'name': 'jason', 'file_size': len(res), 'info': 'great'}
                dump_dict = json.dumps(dic)
    
                # 制作字典报头
                header = struct.pack('i', len(dump_dict))
                # 发送字典报头
                conn.send(header)
                # 发送字典
                conn.send(dump_dict.encode('utf-8'))
                # 发送真实数据
                conn.send(res)
            except ConnectionResetError as e:
                break
    
        conn.close()
  • 相关阅读:
    与众不同 windows phone (50)
    与众不同 windows phone (49)
    重新想象 Windows 8.1 Store Apps (93)
    重新想象 Windows 8.1 Store Apps 系列文章索引
    重新想象 Windows 8.1 Store Apps (92)
    重新想象 Windows 8.1 Store Apps (91)
    重新想象 Windows 8.1 Store Apps (90)
    重新想象 Windows 8.1 Store Apps (89)
    重新想象 Windows 8.1 Store Apps (88)
    重新想象 Windows 8.1 Store Apps (87)
  • 原文地址:https://www.cnblogs.com/AbrahamChen/p/11323021.html
Copyright © 2011-2022 走看看