# -*- coding: utf-8 -*-
import json
import socket
import struct
import sys
import time
import gzip
class Client(object):
def __init__(self, host: str, port: int):
"""
初始化
Args:
host: 建立连接的IP
port: 建立连接的端口
buffer: 一次读取的字节大小
timeout: 超时时间
encoding: 字符编码格式
"""
self.host = host
self.port = port
self.buffer = 512
self.timeout = 10
self._encoding = 'utf-8'
self.tcp_client_socket = None
def connect(self) -> object:
"""
服务端应用程序建立连接
Returns:
"""
# 创建tcp客户端套接字
# 1. AF_INET:表示ipv4
# 2. SOCK_STREAM: tcp传输协议
try:
self.tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_client_socket.connect((self.host, self.port))
except socket.error as e:
self.tcp_client_socket.close()
time.sleep(5)
print("socket连接失败,请确认主机是否开启或防护墙是否关闭", e)
self.connect()
return self.tcp_client_socket
def get_response(self, tcp_client_socket) -> dict:
"""
Args:
tcp_client_socket: 连接对象
Returns:
返回服务器传输回来的数据,字符类型
"""
false = False
true = True
null = None
server_dict_data = {}
try:
# 先接收服务端固定长度的头信息,这里固定长度为4 Bytes
header = tcp_client_socket.recv(4)
# AI等待时间长接收到空字节
# 判断 是否为空字节,是直接return header: b'' header_len 0
if header == b'':
server_str_data = {}
print("获取header为空")
sys.exit()
# 从头信息中获取接收数据的总量
header_size = struct.unpack('i', header)[0]
recv_data = tcp_client_socket.recv(header_size)
# 解压缩数据
recv_data = gzip.decompress(recv_data)
# 转为字符串
server_str_data = recv_data.decode('utf-8')
server_str_data = server_str_data.replace('null', 'None').replace('false', 'False').replace('true', 'True')
server_dict_data = eval(server_str_data)
except Exception as e:
sys.exit()
# 后期在此地方处理id信息
return server_dict_data
def send_data(self, send_data: dict) -> bool:
"""
发送数据
Args:
send_data: 发送数据体,默认为bytes格式
Returns:
True:发送成功
False:发送成功
"""
# 发送socket消息携带包头
if send_data.get('id') != 9999:
print(f"C->S:{send_data}")
send_data = str(send_data)
msg_bs = send_data.encode("utf-8")
# 压缩数据体
msg_bs = gzip.compress(msg_bs)
msg_struct_len = struct.pack("i", len(msg_bs))
send_data = msg_struct_len + msg_bs
# 数据进行解码, 判断是否为字典类型
try:
if isinstance(send_data, dict):
dict_to_json_data = self.dict_to_json(send_data)
self.tcp_client_socket.send(dict_to_json_data)
else:
self.tcp_client_socket.send(send_data)
except Exception as e:
return False
return True
def close_client(self):
"""
关闭套接字
Returns:
"""
self.tcp_client_socket.close()
print("socket 已关闭")
def dict_to_json(self, data: dict):
"""
python字典转JSON格式
Args:
data: 传入python字典
Returns:
返回JSON格式数据
"""
try:
dict_to_json = json.dumps(data)
json_data = dict_to_json.encode("utf-8")
except Exception as e:
raise e
return json_data
def json_to_dict(self, data: json):
"""
python JSON转字典格式
Args:
data: 传入JSON
Returns:
返回字典格式数据
"""
try:
json_data = json.loads(data)
except Exception as e:
raise e
return json_data
转发请注明出处!感谢!