前言
记录一些学习经验、遇到的问题
一、基础设置
服务器
###非阻塞型
import socketserver
import json
from os import popen
from time import strftime,localtime
def logging(jd_event,jd_client_address,jd_command,jd_data):
txt1 = open("log.txt", "a+")
log_time = strftime("%Y/%m/%d %H:%M:%S", localtime()) # 日志时间
log_level = jd_event # 日志级别
log_client_address = jd_client_address # IP地址和端口
log_cmd = jd_command # 命令
log_record = jd_data # 插入数据
txt1.write("\n")
txt1.write(f"[{log_time}][{log_level}][{log_client_address} {log_cmd}]{log_record}")
txt1.close()
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
try:
while True:
self.data = self.request.recv(2048)
self.jd = json.loads(self.data.decode(encoding='utf8')) # 接收数据utf8解码后,再进行json解码
if self.jd['COMMAND'] == 'SEND_DATA': # 单纯发送数据
print("{} {} : {}".format(self.client_address, self.jd['COMMAND'], self.jd['data']))
logging('info',self.client_address,self.jd['COMMAND'],self.jd['data'])
### 执行成功后返回执行结果
self.jd['reslut'] = "发送成功"
self.jsonstr = json.dumps(self.jd)
self.request.sendall(self.jsonstr.encode('utf8'))
elif self.jd['COMMAND'] == 'Execute_Cmd': # 执行命令
self.exec_command = popen(self.jd['data']) # 输入命令
self.result = self.exec_command.read() # 获取结果
self.exec_command.close() # 关闭连接
print("{} {} : {}".format(self.client_address, self.jd['COMMAND'], self.jd['data']))
logging('info', self.client_address, self.jd['COMMAND'], self.jd['data'])
### 执行成功后返回执行结果
self.jd['reslut'] = "执行成功"
self.jd['Execute_reslut'] = self.result
self.jsonstr = json.dumps(self.jd)
self.request.sendall(self.jsonstr.encode('utf8'))
if not self.data: # 没有数据,关闭
print("connection lost")
break
except Exception as e:
# print(e)
print(self.client_address, "连接断开")
logging('info', self.client_address, "disconnect", "连接断开")
finally:
self.request.close()
def setup(self): # 显示链接地址和端口(方法handle之前执行)
print("before handle,连接建立:", self.client_address)
logging('info', self.client_address, "connect", "连接成功")
# def finish(self): (方法handle之后执行)
# print("finish run after handle")
if __name__ == '__main__':
HOST, PORT = "localhost", 9999
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler) # 多线程版
server.serve_forever()
客户端
import socket
import json
def command_mode():
global parameter_mode
### 用于设置命令模式
parameter_mode = 0
while True:
parameter_mode = input("1、发送消息 2、执行命令 >>")
if parameter_mode == 1 or parameter_mode == 2: break
elif parameter_mode == '1' or parameter_mode == '2': break
else: continue
if __name__ == '__main__':
client = socket.socket()
client.connect(('localhost', 9999))
parameter_mode = 0
command_mode()
while True:
data = input("(quit退出、exit返回)>>").strip()
if len(data) == 0: continue
if data == "quit": break
if data == "exit": command_mode()
if parameter_mode == 1 or parameter_mode == '1':
### 对消息进行编码并发送
jd = {}
jd['COMMAND'] = "SEND_DATA" # 执行什么命令
jd['data'] = data # 数据
jsonstr = json.dumps(jd) # 将要发送的数据进行 json编码
client.sendall(jsonstr.encode('utf8')) # 将已经json编码的数据进行utf8编码并发送
### 接收服务器发送回来的结果
data_res = client.recv(2048)
jd_rec = json.loads(data_res.decode(encoding='utf8'))
print(jd_rec['reslut'], jd_rec['data'])
elif parameter_mode == 2 or parameter_mode == '2':
### 对消息进行编码并发送
jd = {}
jd['COMMAND'] = "Execute_Cmd" # 执行什么命令
jd['data'] = data # 数据
jsonstr = json.dumps(jd) # 将要发送的数据进行 json编码
client.sendall(jsonstr.encode('utf8')) # 将已经json编码的数据进行utf8编码并发送
### 接收服务器发送回来的结果
data_res = client.recv(9999)
jd_rec = json.loads(data_res.decode(encoding='utf8'))
print(jd_rec['reslut'], jd_rec['data'])
print(jd_rec['Execute_reslut'])
client.close()