20230908_python练习_服务端与客户端数据交互

	用户可以通过简单操作进行服务端数据交互,通过简单的sql语句直接获取EXCEL表,可以用来作为交互的基础。

主要涉及三部分:

1:数据库存储表结构
在这里插入图片描述

--日志记录表结构
create table shzc.yytowz_service_title
(leixing  varchar2(18),ziduan1  varchar2(3000),ziduan2  varchar2(300),ziduan3  varchar2(300),ip_id  varchar2(18),
post_id  varchar2(18),in_time varchar2(30),mac varchar2(20),hostname varchar2(100),ip varchar2(30) );

2:服务端维持代码
在这里插入图片描述

# 服务端
import socketserver
import json
import os
#import pymysql
import cx_Oracle #Oracle 数据库连接
import time
import tqdm
import pandas as pdclass MyServer(socketserver.BaseRequestHandler):def handle(self):self.add_ip = self.client_address[0]self.add_post = str(self.client_address[1])while True:try:data = self.request.recv(102400)#如果获取为空就退出if not data:break#否则解码处理数据self.data = json.loads(data.decode('utf-8'))# data 是获取字典内容,self.client_address 是 ip地址与 端口print('客户端的消息:',self.data,self.client_address)#数据库对访问记录存档self.log_record()# 定义处理规则self.visit_response()#将结果反馈给客户端self.request.sendall(self.fankui.encode('utf-8'))except :#print('连接异常')break#定义处理规则def visit_response(self):#获取时间in_time = self.get_current_time()[0:14]if self.data['leixing'] == '文件传递':try:file_download_statr = self.file_download()self.fankui = '{"leixing":"%s","ziduan1":"%s","ziduan2":"%s","ziduan3":"%s" }' % (self.data['leixing'], self.add_ip, self.add_post, file_download_statr)except:self.fankui = '{"leixing":"%s","ziduan1":"%s","ziduan2":"%s","ziduan3":"%s" }' % (self.data['leixing'], self.add_ip, self.add_post, '传递失败')elif self.data['leixing'] == '文件下载': # 获取sql语句生成表格download_start, file_path, file_name, file_size = Oracle_download(self.data['mac'], in_time,str(self.data['ziduan1']).replace("^","'"))print('download_start', download_start, '大小字节', file_size, '文件名', file_name)try:# 将表格返回客户端file_download_statr = self.file_up(file_path,self.data['ziduan3'])self.fankui = '{"leixing":"%s","ziduan1":"%s","ziduan2":"%s","ziduan3":"%s" }' % (self.data['leixing'], file_path, file_size, file_download_statr)except:self.fankui = '{"leixing":"%s","ziduan1":"%s","ziduan2":"%s","ziduan3":"%s" }' % (self.data['leixing'], file_path, file_size, '传递失败')elif self.data['leixing'] == '发起访问':try:self.fankui = '{"leixing":"%s","ziduan1":"%s","ziduan2":"%s","ziduan3":"%s" }' % (self.data['leixing'], self.add_ip, self.add_post, '访问成功')except:self.fankui = '{"leixing":"%s","ziduan1":"%s","ziduan2":"%s","ziduan3":"%s" }' % (self.data['leixing'], self.add_ip, self.add_post, '访问失败')else:try:self.fankui = '{"leixing":"%s","ziduan1":"%s","ziduan2":"%s","ziduan3":"%s" }' % (self.data['leixing'], self.add_ip, self.add_post, '访问成功')except:self.fankui = '{"leixing":"%s","ziduan1":"%s","ziduan2":"%s","ziduan3":"%s" }' % (self.data['leixing'], self.add_ip, self.add_post, '访问失败')#文件下载函数def file_download(self):in_time = self.get_current_time()[0:14]file_path = self.data['ziduan1']file_size = self.data['ziduan2']file_hz = file_path.split('/')[-1]print('接收文件名:',file_hz,' 接收文件大小:',file_size,' 字节')# 文件传输的缓冲区BUFFER_SIZE = 4096# 接受客户端信息filename, file_size, new_filename = self.data['ziduan1'], self.data['ziduan2'], str(self.data['ziduan3'])[0:6]#判断月文件夹是否存在,不存在创建一个file_path_state1 = os.path.exists('./file_server/'+new_filename)if file_path_state1 == False:os.mkdir('./file_server/'+new_filename)# 获取文件的名字filename = os.path.basename(filename)file_size = int(file_size)if os.path.isfile(filename):f = open('./file_server/'+new_filename +'/' + self.data['mac'] + '_' + in_time + '_' + file_hz, "wb")else:f = open('./file_server/'+new_filename +'/' + self.data['mac'] + '_' + in_time + '_' + file_hz, "wb")rece_size = 0while rece_size < file_size:data = self.request.recv(BUFFER_SIZE)f.write(data)rece_size += len(data)else:return '传递成功'def file_up(self,fujian_label,in_time):# 文件传输的缓冲区BUFFER_SIZE = 4096# 传递文件到指定目录下filename = fujian_label.replace('/', '//')# 文件大小file_size = os.path.getsize(filename)# 创建连接chuandi_tup = '{"leixing":"%s","ziduan1":"%s","ziduan2":"%d","ziduan3":"%s" }' % ('文件提取', filename, file_size, in_time)self.request.sendall(chuandi_tup.encode('utf-8'))# 文件传输progress = tqdm.tqdm(range(file_size), f"发送{filename}", unit="B", unit_divisor=1024)with open(filename, "rb") as f:for _ in progress:# 读取文件bytes_read = f.read(BUFFER_SIZE)if not bytes_read:break# sendall确保及时网络忙碌的时候,数据仍然可以传输self.request.sendall(bytes_read)progress.update(len(bytes_read))# 关闭资源self.request.close()#数据库登录def mysql_execute(self, in_sql, leixing):# 登录数据库dsn = "134.80.200.216/xxx"try:conn = cx_Oracle.connect(user="zbweb", password="zibo_xxx", dsn=dsn, encoding="UTF-8")except:time.sleep(10)conn = cx_Oracle.connect(user="zbweb", password="zibo_xxx", dsn=dsn, encoding="UTF-8")# 得到一个可以执行SQL语句的光标对象cursor = conn.cursor()# 数据库执行导入的语句if leixing == '数量':# 反馈数量count = cursor.execute(in_sql)elif leixing == '单条':# 反馈单条cursor.execute(in_sql)count = cursor.fetchone()[0]elif leixing == '多条':# 反馈多条cursor.execute(in_sql)count = cursor.fetchall()elif leixing == '编辑':count = cursor.execute(in_sql)conn.commit()# 关闭光标对象cursor.close()# 关闭数据库连接conn.close()# 反馈return count# 时间计算def get_current_time(self):ct = time.time()local_time = time.localtime(ct)data_head = time.strftime("%Y%m%d%H%M%S", local_time)data_secs = abs(ct - round(ct)) * 1000time_stamp = "%s%03d" % (data_head, data_secs)return time_stamp#日志留存def log_record(self):in_time = self.get_current_time()[0:14]ziduan1 = str(self.data['ziduan1']).replace("'","^")sql = "insert into shzc.yytowz_service_title (leixing,ziduan1,ziduan2,ziduan3,ip_id,post_id,in_time,mac,hostname,ip) values('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s') " % (self.data['leixing'], ziduan1, self.data['ziduan2'], self.data['ziduan3'], str(self.client_address[0]),str(self.client_address[1]),in_time, self.data['mac'], self.data['hostname'], self.data['ip'])num = self.mysql_execute(sql,'编辑')#print('num',num)return num# 时间计算
def get_current_time(input_date='0'):# 如果时间传入为空if input_date == '0':ct = time.time() # - 24 * 60 * 60  #如果是取昨天日期是减数值local_time = time.localtime(ct)data_head = time.strftime("%Y%m%d%H%M%S", local_time)data_secs = abs(ct - round(ct)) * 1000time_stamp = "%s%03d" % (data_head, data_secs)else:time_stamp = input_date + '120000001'return time_stampdef file_transfer(user,file_name):#获取月份in_month = get_current_time()[0:6]# 文件传递给服务器file_path = file_namefile_statr = user.file_up(file_path, in_month)# 如果执行结果不成功,再次执行一次,保底if file_statr['ziduan3'] != '传递成功':file_statr = file_transfer(user,file_name)return file_statrelse:return file_statr#这里用作程序预备,目前建立必要的文件夹
def server_init():# 程序执行前先确认 ./file_server/ 是否存在,不存在新建file_path_state1 = os.path.exists('./file_server')if file_path_state1 == False:os.mkdir('./file_server')file_path_state1 = os.path.exists('./file_server/file_out')if file_path_state1 == False: os.mkdir('./file_server/file_out')#文件数据生成,分mac与时间,不然没法同步下载
def Oracle_download(mac,in_time,sql='0'):# 结果数据生成表格准备发送dsn = "134.80.200.216/pdbzbjs1"conn = cx_Oracle.connect(user="zbweb", password="zibo_533_03", dsn=dsn, encoding="UTF-8")df = pd.read_sql("""%s""" % sql, con=conn)df.to_excel("./file_server/file_out/"+mac+"_"+in_time+"_结果下载.xlsx", index=False)# 文件大小file_path = './file_server/file_out/'+mac+'_'+in_time+'_结果下载.xlsx'file_name = file_path.split('/')[-1]file_size = os.path.getsize(file_path)#返回根据语句处理结果与return "结果下载",file_path,file_name,file_sizeif __name__ == '__main__':#服务器文件夹准备server_init()#服务器开始s = socketserver.ThreadingTCPServer(('134.35.10.10', 8967), MyServer)#类似实现连接循环s.serve_forever()

3:客户端代码
在这里插入图片描述

# 客户端
import socket
import json
import time
import os
import tqdm
import uuid #获取系统macclass My_Main():def __init__(self):# 程序执行前先确认 ./file_server/file_work_order/ 是否存在,不存在新建file_path_state1 = os.path.exists('./file_main')if file_path_state1 == False: os.mkdir('./file_main')# 定义服务端地址self.ip_num, self.port_num = '134.35.10.10', 8967# macself.mac = uuid.UUID(int=uuid.getnode()).hex[-12:]# 获取主机名self.hostname = socket.gethostname()# 获取IPself.ip = socket.gethostbyname(self.hostname)#发起访问调用模块def socket_dlgc(self,leixing, name_text, pass_text):# 获取14位长度时间,年月日时分秒的self.in_time = get_current_time()[0:14]tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcp_client.connect((self.ip_num, self.port_num))if None == name_text:print('与服务器断开连接')#发送msg = '{"leixing":"%s","ziduan1":"%s","ziduan2":"%s","ziduan3":"%s","mac":"%s","hostname":"%s","ip":"%s" }' % (str(leixing), str(name_text), str(pass_text), self.in_time,self.mac, self.hostname, self.ip)tcp_client.send(msg.encode("utf-8"))  # 说话    #data = tcp_client.recv(102400)  # 听话js_data = json.loads(data.decode('utf-8'))tcp_client.close()return js_data# 文件下载函数def file_download(self,sql):# 获取14位长度时间,年月日时分秒的self.in_time = get_current_time()[0:14]# 套接字是对访问的ip地址和端口反馈,需要从开始定好tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcp_client.connect((self.ip_num, self.port_num))# 申请数据下载chuandi_tup = '{"leixing":"%s","ziduan1":"%s","ziduan2":"%d","ziduan3":"%s","mac":"%s","hostname":"%s","ip":"%s" }' % ('文件下载', sql, 1, self.in_time+'.xlsx',self.mac, self.hostname, self.ip)tcp_client.send(chuandi_tup.encode("utf-8"))  # 说话self.data = tcp_client.recv(102400)  # 听话js_data = json.loads(self.data.decode('utf-8'))#print(js_data, type(js_data))if js_data['ziduan1'] not in ('', None):file_size = int(js_data['ziduan2'])#print(file_size)filename = js_data['ziduan3']rece_size = 0recv_data = tcp_client.recv(4096)if recv_data:  # 如果获取数据不为空try:with open('./file_main/' + filename, "wb")as f:f.write(recv_data)while rece_size < file_size:recv_data = tcp_client.recv(4096)f.write(recv_data)rece_size += len(self.data)js_data = {'leixing': '文件下载', 'ziduan1': js_data['ziduan3'], 'ziduan2': file_size, 'ziduan3': '传递成功'}except:js_data = {'leixing': '文件下载', 'ziduan1': js_data['ziduan3'], 'ziduan2': file_size, 'ziduan3': '传递失败'}# 关闭套接字tcp_client.close()return js_data#客户端文件上传,fujian_label 文件全路径def file_up(self,fujian_label):# 获取14位长度时间,年月日时分秒的self.in_time = get_current_time()[0:14]# 文件传输的缓冲区BUFFER_SIZE = 4096# 创建连接s = socket.socket()s.connect((self.ip_num, self.port_num))# 传递文件到指定目录下filename = fujian_label.replace('/', '//')# 文件大小file_size = os.path.getsize(filename)chuandi_tup = '{"leixing":"%s","ziduan1":"%s","ziduan2":"%d","ziduan3":"%s","mac":"%s","hostname":"%s","ip":"%s" }' % ('文件传递', filename, file_size, self.in_time,self.mac, self.hostname, self.ip )s.send(chuandi_tup.encode())# 文件传输progress = tqdm.tqdm(range(file_size), f"发送{filename}", unit="B", unit_divisor=BUFFER_SIZE)with open(filename, "rb") as f:for _ in progress:# 读取文件bytes_read = f.read(BUFFER_SIZE)if not bytes_read:breaktry:# sendall确保及时网络忙碌的时候,数据仍然可以传输s.sendall(bytes_read)progress.update(len(bytes_read))except:js_data = {'leixing': '文件传递', 'ziduan1': self.ip_num, 'ziduan2': self.port_num, 'ziduan3': '传递失败'}break#文件传递完后,看看是否有反馈,有的话函数返回try:data = s.recv(102400)  # 听话js_data = json.loads(data.decode('utf-8'))except:js_data = {'leixing': '文件传递', 'ziduan1': self.ip_num, 'ziduan2': self.port_num, 'ziduan3': '传递失败'}# 关闭资源s.close()return js_data# 时间计算
def get_current_time(input_date='0'):# 如果时间传入为空if input_date == '0':ct = time.time() # - 24 * 60 * 60  #如果是取昨天日期是减数值local_time = time.localtime(ct)data_head = time.strftime("%Y%m%d%H%M%S", local_time)data_secs = abs(ct - round(ct)) * 1000time_stamp = "%s%03d" % (data_head, data_secs)else:time_stamp = input_date + '120000001'return time_stamp#文件传递给服务器
def file_transfer(user,file_name,num=0):# 防止有语法错误等原因导致死循环,限制最多处理4次if num < 5:# 文件传递给服务器try:file_statr = user.file_up(file_name)num += 1except:file_statr = {'leixing': '文件传递', 'ziduan1': file_name, 'ziduan2': '0', 'ziduan3': '传递失败'}num += 1# 如果执行结果不成功,再次执行一次,保底if file_statr['ziduan3'] != '传递成功':file_statr = file_transfer(user,file_name,num)return file_statrelse:return file_statrelse:file_statr = {'leixing': '文件传递', 'ziduan1': file_name, 'ziduan2': '0', 'ziduan3': '传递失败'}return file_statr#文件传递给服务器
def file_gain(user,sql,num=0):#防止有语法错误等原因导致死循环,限制最多处理4次if num < 5:# 文件传递给服务器try:file_statr = user.file_download(sql)num += 1except:file_statr = {'leixing': '文件下载', 'ziduan1': sql, 'ziduan2': '0', 'ziduan3': '传递失败'}num += 1# 如果执行结果不成功,再次执行一次,保底if file_statr['ziduan3'] != '传递成功':file_statr = file_gain(user,sql,num)return file_statrelse:return file_statrelse:file_statr = {'leixing': '文件下载', 'ziduan1': sql, 'ziduan2': '0', 'ziduan3': '传递失败'}return file_statrdef use_show():print('请您选择需要处理的类型(请输入选择的编码):')print('类型:发起访问 编码:1')print('类型:文件传递 编码:2')print('类型:文件下载 编码:3')def use_choice(use_input):if use_input == '1':use_type = '发起访问'elif use_input == '2':use_type = '文件传递'elif use_input == '3':use_type = '文件下载'else:use_type = '类型不详'return use_typedef use_decision(user,use_input):if use_input == '1':name_text = input('请您输入需要发起的标题:')pass_text = input('请您输入需要发起的内容:')socket_dlgc_statr = user.socket_dlgc('发起访问', name_text, pass_text)print('系统反馈:', socket_dlgc_statr)elif use_input == '2':wav_write = input('请您输入需要发送文件名:')transfer_statr = file_transfer(user, wav_write)print('系统反馈:',transfer_statr)elif use_input == '3':sql = input('请您输入需要发送的语句:').replace("'","^")gain_statr = file_gain(user, sql)print('系统反馈:', gain_statr)else:use_type = '类型不详'passif __name__ == '__main__':# 加载类user = My_Main()# 循环执行while True:use_show()use_input = input('请您输入选择的编码:')use_type = use_choice(use_input)print('您选择需要处理的类型:',use_type)#类型不详就断开if use_type=='类型不详':breakuse_decision(user, use_input)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/72528.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件测试/测试开发丨学会与 AI 对话,高效提升学习效率

点此获取更多相关资料 简介 ChatGPT 的主要优点之一是它能够理解和响应自然语言输入。在日常生活中&#xff0c;沟通本来就是很重要的一门课程&#xff0c;沟通的过程中表达越清晰&#xff0c;给到的信息越多&#xff0c;那么沟通就越顺畅。 和 ChatGPT 沟通也是同样的道理&…

单目标应用:基于成长优化算法(Growth Optimizer,GO)的微电网优化调度MATLAB

一、微网系统运行优化模型 微电网是由分布式电源、储能装置和能量转换装置等组成的小型发配电系统&#xff0c;具有成本低、电压低、污染小等特点。由于环保和能源压力&#xff0c;清洁可再生能源和分布式能源工业发展潜力巨大。微电网控制器可实现对电网的集中控制&#xff0…

搭建RabbitMQ消息服务,整合SpringBoot实现收发消息

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;3年JAVA全栈开发经验&#xff0c;专注JAVA技术、系统定制、远程指导&#xff0c;致力于企业数字化转型&#xff0c;CSDN博客专家&#xff0c;蓝桥云课认证讲师。 目录 一、前言1.1 什么是消息队列1.2 RabbitMQ 是什么1.…

Linux:【Mysql】Centos7安装mysql8.0

目录 一、环境及版本介绍 二、安装前准备 三、开始安装 一、环境及版本介绍 Linux环境&#xff1a;Centos7 Mysql版本&#xff1a;8.0.26 安装时使用的用户&#xff1a;root 二、安装前准备 1.1、下载Centos7镜像 网上寻找相关资源即可 1.2、下载VMwareWorkstation Pro并…

【LeetCode-中等题】208. 实现 Trie (前缀树)

文章目录 题目方法一&#xff1a;利用数组构建26叉树方法二&#xff1a;利用哈希表构建26叉树 题目 方法一&#xff1a;利用数组构建26叉树 插入图示&#xff1a; 全搜索和前缀搜索&#xff1a; 注意&#xff1a;全局匹配匹配完直接返回插入时的标志位 而前缀匹配时&#xff…

OpenWrt系统开发笔记

openWrt英文官网&#xff1a; https://openwrt.org/ 中文官网&#xff1a; http://www.openwrt.org.cn/ 一、开发环境及编译 在github上有两个源码使用的比较多   一个是lede,地址为&#xff1a;https://github.com/coolsnowwolf/lede   另一个为OpenWrt的官方源码&#…

Redis 管道

1. 面试题 1.1 如何优化频繁命令往返造成的性能瓶颈? 1.2 问题由来 Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。一个请求会遵循以下步骤&#xff1a; 1 客户端向服务端发送命令分四步(发送命令→命令排队→命令执行→返回结果)&#xff0c;并监听Socket返…

Redis 复制(replica)

1. 是什么 1.1 官网地址 https://redis.io/docs/management/replication/ 1.2 一句话 1. 就是主从复制&#xff0c;master以写为主&#xff0c;slave以读为主 2. 当master数据变化的时候&#xff0c;自动将新的数据异步同步到其它slave数据库 2. 能干嘛 1. 读写分离 2. 容灾…

智能化电力运维:数字孪生的崭露头角

随着科技的不断发展&#xff0c;数字孪生技术在各个领域的应用愈发广泛&#xff0c;尤其在电力运维领域&#xff0c;它正发挥着革命性的作用。数字孪生是一种虚拟仿真技术&#xff0c;通过实时模拟真实世界的物理对象或过程&#xff0c;可以从多方面为电力运维带来改变&#xf…

PEX装机

目录 一、PXE是什么&#xff1f; 二、PXE的组件&#xff1a; vsftpd/httpd/nfs tftp dhcp 三、配置vsftpd 四、配置tftp 1.安装tftp-server 2.启动tftp 五、准备pxelinx.0文件、引导文件、内核文件 1.准备pxelinux.0文件 2.准备引导文件、内核文件 六、配置dhcp …

实时操作系统Freertos开坑学习笔记:(八):信号量、事件标志组、任务通知机制

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、信号量的简介1.信号量与队列的区别&#xff1f; 二、二值信号量及其实例1.什么是二值信号量2.二值信号量相关API函数3.二值信号量实例 三、计数型信号量四、…

TD3算法

TD3算法 全称Twin Delayed DDPG&#xff0c;是对DDPG算法的继承、发展和改进&#xff0c;论文 改进如下&#xff1a; T w i n \mathcal{T}win Twin&#xff1a;使用了两个critic来评估actor的动作价值&#xff0c;对应两个critic target&#xff0c;一个actor target&#xff0…

ChatGPT 超有用提示词 练习雅思口语

目录 Prompts &#x1f53b;作为一个英语口语老师和提高英语口语 方法1&#xff1a;口语简单练习 方法2&#xff1a;角色扮演练习口语 作为一个英语翻译/英语作文优化师/稿件校对 作为一个”职位”面试官 学习英文单词 演员 苏菲 玛索 阿尔弗雷多詹姆斯帕西诺 要孝顺…

联合教育部高等学校科学研究发展中心,阿依瓦科技创新教育专项正式发布!

7 月 24 日&#xff0c;教育部科技发展中心官网发布了《中国高校产学研创新基金&#xff0d;阿依瓦科技创新教育专项申请指南》。 针对高校在人工智能、智能制造、智慧校园、大数据等领域科研和教研的创新研究&#xff0c;教育部高等学校科学研究发展中心与阿依瓦(北京)技术有…

Android 自定义View之圆形进度条

很多场景下都用到这种进度条&#xff0c;有的还带动画效果&#xff0c; 今天我也来写一个。 写之前先拆解下它的组成&#xff1a; 底层圆形上层弧形中间文字 那我们要做的就是&#xff1a; 绘制底层圆形&#xff1b;在同位置绘制上层弧形&#xff0c;但颜色不同&#xff…

2651. 计算列车到站时间

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;数学 知识回忆除法运算 写在最后 Tag 【数学】 题目来源 2651. 计算列车到站时间 题目解读 给你一个列车预计到达时间点和一个列车延误的时间&#xff0c;请返回列车实际的到达时间。 解题思路 方法一&#xff1a;数…

C语言每日一练--Day(16)

本专栏为c语言练习专栏&#xff0c;适合刚刚学完c语言的初学者。本专栏每天会不定时更新&#xff0c;通过每天练习&#xff0c;进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字&#xff1a;寻找奇数 峰值 二分查找 &#x1f493;博主csdn个人主页&#xff1a;小…

C# 基础面试题(万字)

1.选择题 1. 简述下面选项能够捕获运算溢出的异常类型的有 &#xff1f; A)Exception B)SystemException C)ArithmeticException D)OverflowException 试题回答&#xff1a;AD 2. 程序员可使用&#xff08;&#xff09;语句以程序方式引发异常 &#xff1f; A)run B)try C)th…

jframe生成柱状图片+图片垂直合并+钉钉机器人推送

需求&#xff1a; 后端根据数据自动生成2个图片&#xff0c;然后把两张图片合并成一张图片&#xff0c;再发到钉钉群里&#xff0c;涉及到定时生成和推送&#xff0c;当时我们测试同事说他们写定时脚本放到服务器上&#xff0c;然后让我提供生成图片的方法和钉钉机器人的逻辑 天…

【计算机网络】UDP协议详解

目录 前言 端口号的拓展 端口号范围划分 netstat pidof UDP协议 UDP协议端格式 UDP的特点 面向数据报 UDP的缓冲区 UDP使用注意事项 基于UDP的应用层协议 前言 我们前面讲完了http和https协议&#xff0c;它们都属于应用层&#xff0c;按照TCP/IP五层模…