zoukankan      html  css  js  c++  java
  • Socket传输简单的信息以及粘包问题的解决

      一、简单的socket程序——传输简短文字:

    # -*- coding: utf-8  -*-
    # -*- Author: WangHW -*-
    import socket
    
    whw_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    whw_client.connect(('127.0.0.1',9001))
    while 1:
        cmd = input('>>>:').strip()
        if not cmd:
            continue
        whw_client.send(cmd.encode('utf-8'))
        recv_data = whw_client.recv(1024)
        data = recv_data.decode('utf-8')
        print('server data:',data)
    client
    # -*- coding: utf-8  -*-
    # -*- Author: WangHW -*-
    import socket
    
    whw_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    whw_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    whw_server.bind(('127.0.0.1',9001))
    whw_server.listen(5)
    print('listening......')
    conn,addr = whw_server.accept()
    #通信循环
    while 1:
        try:
            recv_data = conn.recv(1024)
            data = recv_data.decode('utf-8')
            print('client data:',data)
            conn.send(data.swapcase().encode('utf-8'))
        except ConnectionResetError:
            break
    conn.close()
    server

      演示如下:

    二、模拟SSH命令——解决粘包问题版:

      关于粘包问题的解决方案:

      在服务器端,由于解析出来的命令结果非常多,所以我们在发送结果之前需要先给客户端发送一个“报文”,这个报文保存着具体的命令结果的信息——其中关键的信息就是结果的长度,客户端只有知道这个结果的长度后,才能制定相应的接收规则:

    # -*- coding: utf-8  -*-
    # -*- Author: WangHW -*-
    import socket
    import json
    import struct
    
    whw_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    whw_client.connect(('127.0.0.1',9000))
    while 1:
        try:
            cmd = input('>>>:').strip()
            if not cmd:
                continue
            #发命令
            whw_client.send(cmd.encode('utf-8'))
            #1.收报头长度
            obj = whw_client.recv(10)
            #注意structunpack出来的[0]值为长度信息
            header_size = struct.unpack('i',obj)[0]
            #2.收报头——根据报头长度来收
            header_bytes = whw_client.recv(header_size)
            #3.从报头中解析出'total_size'
            header_json = header_bytes.decode('utf-8')
            header_dic = json.loads(header_json)
            total_size = header_dic['total_size']
            #根据total_size开始接收真实的数据
            recv_size = 0
            recv_data = b''
            while recv_size < total_size:
                res = whw_client.recv(1024)
                recv_data += res
                recv_size += len(res)
            print('命令结果:
    ',recv_data.decode('gbk'))
        except Exception as e:
            whw_client.close()
    client
    # -*- coding: utf-8  -*-
    # -*- Author: WangHW -*-
    import socket
    import subprocess
    import json
    import struct
    
    whw_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    whw_server.bind(('127.0.0.1',9000))
    whw_server.listen(5)
    print('Listening......')
    conn,addr = whw_server.accept()
    while 1:
        try:
            #收命令
            cmd_recv = conn.recv(1024).decode('utf-8')
            #解析命令
            obj = subprocess.Popen(cmd_recv,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
            stdout = obj.stdout.read()
            stderr = obj.stderr.read()
            #将命令返回给客户端
            #1.制作固定报头——注意报头里面要包含数据的总长度!
            header_dic = {'filename':'whw','total_size':len(stdout)+len(stderr)}
            header_json = json.dumps(header_dic)
            header_bytes = header_json.encode('utf-8')
            #2.发送报头长度——struct:把数字打成固定长度
            conn.send(struct.pack('i',len(header_bytes)))
            #3.发送报头
            conn.send(header_bytes)
            #4.发送真实数据
            conn.send(stdout)
            conn.send(stderr)
        except ConnectionResetError:
            break
    
    conn.close()
    server

      演示如下:

     

  • 相关阅读:
    [redis] redis在线系统热迁移的方案与记录
    [golang] go get无法安装官方软件包
    我有关编程语言的一点理解
    [nginx] nginx源码分析--健康检查模块锁分析
    [nginx] nginx的hash与bucket size分析
    [daily][linux] dmesg格式里的时间为什么不准
    [daily] 查看linux程序或操作的kernel内核调用栈
    [go] 像gdb一样使用dlv debug golang程序
    [tls][https][nginx] https的client session cache与session ticket机制分析
    [性能优化] CPU电源管理pstate cstate
  • 原文地址:https://www.cnblogs.com/paulwhw/p/9092629.html
Copyright © 2011-2022 走看看