|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
问题描述:服务端读取报文头、报文体都没问题,但是读取报文尾的时候,内容是跟报文体是一样的,求大神指导
报文 = 报文头(标识报文体长度) + 报文体 + 报文尾(标识报文体的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("服务端关闭")
复制代码
|
|