zzz_1015 发表于 2022-11-6 14:05:33

Python socketserver求助:服务端读取不同位置的报文,print出来是一样的


问题描述:服务端读取报文头、报文体都没问题,但是读取报文尾的时候,内容是跟报文体是一样的,求大神指导

报文 = 报文头(标识报文体长度) + 报文体 + 报文尾(标识报文体的hash值,用于校验报文是否被篡改)

客户端
import socket
import time
import json
import traceback


def connect(ip, port):
    server_ip = ip
    server_port = port
    tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
      tcp_client.connect((server_ip, server_port))
    except socket.error:
      print('连接失败!!!')
    return tcp_client


def recv_msg(conn, length: int):
    ret_msg = bytes()
    recv_len = length
    while recv_len > 0:
      msg = conn.recv(recv_len)
      ret_msg += msg
      cur_len = len(msg)
      recv_len -= cur_len
    return ret_msg


def send_msg(tcp_client):
    try:
      data = dict()
      data['name'] = 'login'
      data['user_id'] = '8888'
      data['password'] = '123456'
      # for i in range(1000):
      #   data['demo_field_{}'.format(
      #         i)] = 'sdflakswdfnasdlfkjalnsdfknalksdjflkjaslkdfjlksajdflkjalksdfjlkasjdfklajslkdfjklsadjflks_{}'.format(
      #         i)

      data['time'] = time.strftime("%Y-%m-%d")
      # dict转json
      str_json = json.dumps(data)
      # 计算长度
      length = len(str_json)
      head = length.to_bytes(4, byteorder='big', signed=False)
      #计算hash值
      client_hash = "{:0>20}".format(str(hash(str_json)))
      # 拼装报文头与报文体
      msg = head + str_json.encode('utf-8') + client_hash.encode('utf-8')
      print(msg)
      tcp_client.send(msg)

      # 1.先接收头四位报文头
      len_msg = tcp_client.recv(4)
      length = int.from_bytes(len_msg, byteorder='big', signed=False)

      print('客户端收到报文长度:{}'.format(length))
      # 2.再接收报文体
      req_msg = recv_msg(tcp_client, length)
      json_str = str(req_msg, encoding='utf-8')
      print('客户端收到报文str:{}'.format(json_str))
      req_msg_dict = json.loads(json_str)
      # print('客户端收到报文dict:{}'.format(req_msg_dict))
    except Exception as e:
      print('连接失败!!!')
      traceback.print_exc()
      raise e


IP = '127.0.0.1'
PORT = 12581
if __name__ == '__main__':
    conn = connect(ip=IP, port=PORT)
    send_msg(conn)
    conn.close()



服务端
from socketserver import ThreadingTCPServer
from socketserver import StreamRequestHandler
import json
import traceback


def recv_msg(conn, length: int):
    ret_msg = bytes()
    recv_len = length
    while recv_len > 0:
      msg = conn.read(recv_len)
      ret_msg += msg
      cur_len = len(msg)
      recv_len -= cur_len
    return ret_msg


class MyStreamRequestHandler(StreamRequestHandler):

    def handle(self):
      print('连接上来啦, 连接号:[{0}]'.format(self.wfile))
      while True:
            try:
                print("等待客户端发送报文...")
                # 1.先接收头四位报文头
                len_msg = self.rfile.read(4)
                if len_msg:
                  length = int.from_bytes(len_msg, byteorder='big', signed=False)
                  print('服务端收到报文长度:{}'.format(length))
                  # 2.再接收报文体
                  req_msg = recv_msg(self.rfile, length)
                  # req_msg = self.rfile.read(length)
                  #接收报文尾
                  req_hash = str(self.rfile.read(20),encoding='utf-8')
                  json_str = str(req_msg, encoding='utf-8')
                  print('服务端收到报文str:{}'.format(json_str))
                  print('服务端收到hash:{}'.format(req_hash))
                  req_msg_dict = json.loads(str(req_msg, encoding='utf-8'))
                  # print('服务端收到报文dict:{}'.format(req_msg_dict))
                  # 发送应答
                  head = length.to_bytes(4, byteorder='big', signed=False)
                  rsp_msg = head + bytes(json.dumps(req_msg_dict), encoding='utf-8')
                  print('服务端发送应答报文:{}'.format(rsp_msg))
                  self.wfile.write(rsp_msg)
                else:
                  # 客户端主动断开后,req_msg是b''
                  print('连接已断开, 连接号:[{0}]'.format(self.wfile))
                  break
            except Exception as e:
                print('Socket异常:{}'.format(e))
                traceback.print_exc()
                break

      self.request.close()


def start_server(port: int):
    # 设置IP 和 Port
    addr = ('0.0.0.0', port)
    # 使用socketserver库
    server = ThreadingTCPServer(addr, MyStreamRequestHandler)
    # 启动服务,线程挂起
    server.serve_forever()


PORT = 12581
if __name__ == '__main__':
    print("启动服务端!!!")
    start_server(PORT)
    print("服务端关闭")

zzz_1015 发表于 2022-11-6 14:20:08

原理--不知道,但是原因好像是我改了服务端但是没有重启服务端的原因
页: [1]
查看完整版本: Python socketserver求助:服务端读取不同位置的报文,print出来是一样的