当前位置: 首页 > news >正文

20241305 2025-2026-2 《Python程序设计》实验三报告

20241305 2025-2026-2 《Python程序设计》实验三报告

课程:《Python程序设计》
班级: 2413
姓名: 姚航
学号:20241305
实验教师:王志强
实验日期:2026年4月27日
必修/选修: 公选课

1.实验内容

1.1实验内容

创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。

1.2实验要求

注意事项:

每人必须做一次客户端和一次服务端,且要和队友(标注学号姓名 本次实验由20241317文彩懿协助完成)互相通信。

要求1:

(1)创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序;

(2)要求发送方输入内容,加密后并传输;接收方收到密文并解密和显示。要求:发方和收方同时输出明文和明文。

(3)程序代码托管到码云。

(4)添加文件操作,有加分。(可选项)

要求2:使用LLM生成一个带图形界面的程序

(1)分析关键代码的功能和使用方法

(2)分析生成程序的优点

(3)给出运行过程和结果截图

(4)程序代码托管到码云。

注:在华为ECS服务器(OpenOuler系统)和物理机(Windows/Linux系统)上使用VIM、PDB、IDLE、Pycharm等工具编程实现。

2. 实验过程及结果

2.1创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序
通信端口选择 6666
创建服务端和客户端代码如下:
服务端
这里将服务端设为 0.0.0.0 ,作为“万能监听地址”,能够实现接受来自同一局域网内任意设备(客户端)的连接请求。

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = '0.0.0.0'
PORT = 6666
server.bind((HOST, PORT))
server.listen(1)
print("服务端已经启动,等待客户端连接......")
conn, addr = server.accept()
print(f"已连接客户端:{addr}")

客户端
对应队友的ip配置(学号17收尾),两台电脑全程共同连一个热点,热点ip为10.125.90.xx(根据学号作修改)

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = '10.125.90.17'
PORT = 6666
client.connect((HOST, PORT))
print("已连接服务端!输入exit退出聊天!")

2.2要求发送方输入内容,加密后并传输;接收方收到密文并解密和显示。要求:发方和收方同时输出明文和明文
先附上全部代码,本次采用的加密方式为字符转ASCll数字再移3位
服务端全部代码:

import socketoffset = 3
#加密解密算法采用:字符转ASCll数字再移位
def encrypt(msg):res = ""for c in msg:num = ord(c)new_num = num + offsetnew_ch = chr(new_num)res = res + new_chreturn resdef decrypt(msg):res = ""for c in msg:num = ord(c)new_num = num - offsetnew_ch = chr(new_num)res = res + new_chreturn resserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = '0.0.0.0'
PORT = 6666
server.bind((HOST, PORT))
server.listen(1)
print("服务端已经启动,等待客户端连接......")
conn, addr = server.accept()
print(f"已连接客户端:{addr}")while True:data = conn.recv(1024).decode("utf-8")if not data or data == "exit":print("聊天结束")breakprint("客户端密文:",data)text = decrypt(data)print("客户端明文:",text)send_msg = input("我:")secret = encrypt(send_msg)conn.send(secret.encode("utf-8"))print("我方密文:",secret)if send_msg == "exit":breakconn.close()
server.close()

客户端全部代码:

import socketoffset = 3
#加密解密算法采用:字符转ASCll数字再移位
def encrypt(msg):res = ""for c in msg:num = ord(c)new_num = num + offsetnew_ch = chr(new_num)res = res + new_chreturn resdef decrypt(msg):res = ""for c in msg:num = ord(c)new_num = num - offsetnew_ch = chr(new_num)res = res + new_chreturn resclient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = '10.125.90.17'
PORT = 6666
client.connect((HOST, PORT))
print("已连接服务端!输入exit退出聊天!")while True:send_msg = input("我:")secret = encrypt(send_msg)client.send(secret.encode("utf-8"))print("我方密文:",secret)if send_msg == "exit":breakdata = client.recv(1024).decode("utf-8")if not data or data == "exit":print("聊天结束")breakprint("服务端密文:",data)text = decrypt(data)print("服务端明文:",text)client.close()

进行通信并截图:
我作服务端运行
fe0cfdb9ecbbd831b4d7b97e849ddd26

我作客户端运行
dde07bd25eb4dda69306bca161990e79

这里同时附上队友作服务端和客户端的运行结果截图
f1a39b772df3beeb9fc6571a3c682985
35cafefe7d4aa0b074e5b131766b08c1

2.3程序代码托管到码云
仓库地址

2.4使用LLM生成一个带图形界面的程序
代码附上(选择的加密方式为AES加密,端口选择12345(避免出错),ip为对应学号收尾)
服务端代码

import socket
import threading
import tkinter as tk
from tkinter import scrolledtext, filedialog, messagebox
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
import osHOST = '0.0.0.0'
PORT = 12345
KEY = b'1234567890abcdef'class ServerGUI:def __init__(self, root):self.root = rootself.root.title("服务端 - 加密通信+文件传输")self.root.geometry("700x600")self.conn = Noneself.client_addr = Noneself.setup_ui()self.server_thread = threading.Thread(target=self.start_server, daemon=True)self.server_thread.start()def setup_ui(self):self.log_area = scrolledtext.ScrolledText(self.root, wrap=tk.WORD, width=80, height=20)self.log_area.pack(pady=10, padx=10)self.msg_frame = tk.Frame(self.root)self.msg_frame.pack(pady=5, padx=10, fill=tk.X)tk.Label(self.msg_frame, text="发送消息:").pack(side=tk.LEFT, padx=5)self.msg_entry = tk.Entry(self.msg_frame, width=50)self.msg_entry.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)self.send_btn = tk.Button(self.msg_frame, text="发送文本", command=self.send_text)self.send_btn.pack(side=tk.LEFT, padx=5)self.file_frame = tk.Frame(self.root)self.file_frame.pack(pady=5, padx=10, fill=tk.X)self.file_path = tk.StringVar()tk.Button(self.file_frame, text="选择文件", command=self.select_file).pack(side=tk.LEFT, padx=5)self.file_label = tk.Label(self.file_frame, textvariable=self.file_path, width=40)self.file_label.pack(side=tk.LEFT, padx=5)self.send_file_btn = tk.Button(self.file_frame, text="发送文件", command=self.send_file, state=tk.DISABLED)self.send_file_btn.pack(side=tk.LEFT, padx=5)def log(self, text):self.log_area.insert(tk.END, text + "\n")self.log_area.yview(tk.END)def select_file(self):path = filedialog.askopenfilename()if path:self.file_path.set(path)self.send_file_btn.config(state=tk.NORMAL)def encrypt_data(self, data):iv = get_random_bytes(16)cipher = AES.new(KEY, AES.MODE_CBC, iv)return iv + cipher.encrypt(pad(data, AES.block_size))def decrypt_data(self, data):iv = data[:16]cipher = AES.new(KEY, AES.MODE_CBC, iv)return unpad(cipher.decrypt(data[16:]), AES.block_size)def send_text(self):if not self.conn:messagebox.showerror("错误", "客户端未连接")returntext = self.msg_entry.get().strip()if not text: returntry:plain = text.encode()enc = self.encrypt_data(plain)self.conn.sendall((0).to_bytes(4, 'big'))self.conn.sendall(len(enc).to_bytes(4, 'big'))self.conn.sendall(enc)self.log(f"【发送明文】{text}")self.log(f"【发送密文】{enc.hex()}\n")self.msg_entry.delete(0, tk.END)except:self.log("发送失败")def send_file(self):if not self.conn: returnpath = self.file_path.get()if not os.path.exists(path): returntry:fn = os.path.basename(path)fsize = os.path.getsize(path)with open(path, 'rb') as f:data = f.read()enc = self.encrypt_data(data)self.conn.sendall((1).to_bytes(4, 'big'))self.conn.sendall(len(fn.encode()).to_bytes(4, 'big'))self.conn.sendall(fn.encode())self.conn.sendall(fsize.to_bytes(8, 'big'))self.conn.sendall(len(enc).to_bytes(4, 'big'))self.conn.sendall(enc)self.log(f"【文件发送成功】{fn}")except:self.log("文件发送失败")def handle_client(self):while True:try:typ = int.from_bytes(self.conn.recv(4), 'big')if typ == 0:l = int.from_bytes(self.conn.recv(4), 'big')d = self.conn.recv(l)txt = self.decrypt_data(d).decode()self.log(f"【接收明文】{txt}")self.log(f"【接收密文】{d.hex()}\n")elif typ == 1:fnl = int.from_bytes(self.conn.recv(4), 'big')fn = self.conn.recv(fnl).decode()fsz = int.from_bytes(self.conn.recv(8), 'big')l = int.from_bytes(self.conn.recv(4), 'big')d = self.conn.recv(l)raw = self.decrypt_data(d)with open(f"recv_{fn}", 'wb') as f:f.write(raw)self.log(f"【收到文件】{fn} 已保存")self.log(f"【文件密文】{d.hex()}\n")except:self.log("客户端断开")self.conn = Nonebreakdef start_server(self):with socket.socket() as s:s.bind((HOST, PORT))s.listen(1)self.log(f"服务端已启动,端口 {PORT}")while True:self.conn, addr = s.accept()self.log(f"客户端已连接:{addr}")threading.Thread(target=self.handle_client, daemon=True).start()if __name__ == "__main__":root = tk.Tk()app = ServerGUI(root)root.mainloop()

客户端代码

import socket
import threading
import tkinter as tk
from tkinter import scrolledtext, filedialog, messagebox
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
import osHOST = '10.125.90.17'  # 服务端电脑的IP
PORT = 12345
KEY = b'1234567890abcdef'
# ======================================================class ClientGUI:def __init__(self, root):self.root = rootself.root.title("客户端 - 加密通信+文件传输")self.root.geometry("700x600")self.sock = Noneself.connected = Falseself.setup_ui()threading.Thread(target=self.connect_server, daemon=True).start()def setup_ui(self):self.log_area = scrolledtext.ScrolledText(self.root, wrap=tk.WORD, width=80, height=20)self.log_area.pack(pady=10, padx=10)self.msg_frame = tk.Frame(self.root)self.msg_frame.pack(pady=5, padx=10, fill=tk.X)tk.Label(self.msg_frame, text="发送消息:").pack(side=tk.LEFT, padx=5)self.msg_entry = tk.Entry(self.msg_frame, width=50)self.msg_entry.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)self.send_btn = tk.Button(self.msg_frame, text="发送文本", command=self.send_text)self.send_btn.pack(side=tk.LEFT, padx=5)self.file_frame = tk.Frame(self.root)self.file_frame.pack(pady=5, padx=10, fill=tk.X)self.file_path = tk.StringVar()tk.Button(self.file_frame, text="选择文件", command=self.select_file).pack(side=tk.LEFT, padx=5)self.file_label = tk.Label(self.file_frame, textvariable=self.file_path, width=40)self.file_label.pack(side=tk.LEFT, padx=5)self.send_file_btn = tk.Button(self.file_frame, text="发送文件", command=self.send_file, state=tk.DISABLED)self.send_file_btn.pack(side=tk.LEFT, padx=5)def log(self, text):self.log_area.insert(tk.END, text + "\n")self.log_area.yview(tk.END)def encrypt_data(self, data):iv = get_random_bytes(16)cipher = AES.new(KEY, AES.MODE_CBC, iv)return iv + cipher.encrypt(pad(data, AES.block_size))def decrypt_data(self, data):iv = data[:16]cipher = AES.new(KEY, AES.MODE_CBC, iv)return unpad(cipher.decrypt(data[16:]), AES.block_size)def select_file(self):path = filedialog.askopenfilename()if path:self.file_path.set(path)self.send_file_btn.config(state=tk.NORMAL)def send_text(self):if not self.connected:messagebox.showerror("错误","未连接服务端")returntext = self.msg_entry.get().strip()if not text: returntry:plain = text.encode()enc = self.encrypt_data(plain)self.sock.sendall((0).to_bytes(4,'big'))self.sock.sendall(len(enc).to_bytes(4,'big'))self.sock.sendall(enc)self.log(f"【发送明文】{text}")self.log(f"【发送密文】{enc.hex()}\n")self.msg_entry.delete(0,tk.END)except:self.log("发送失败")def send_file(self):if not self.connected: returnpath = self.file_path.get()if not os.path.exists(path): returntry:fn = os.path.basename(path)fsz = os.path.getsize(path)with open(path,'rb') as f:data = f.read()enc = self.encrypt_data(data)self.sock.sendall((1).to_bytes(4,'big'))self.sock.sendall(len(fn.encode()).to_bytes(4,'big'))self.sock.sendall(fn.encode())self.sock.sendall(fsz.to_bytes(8,'big'))self.sock.sendall(len(enc).to_bytes(4,'big'))self.sock.sendall(enc)self.log(f"【文件发送成功】{fn}")except:self.log("文件发送失败")def receive_loop(self):while self.connected:try:typ = int.from_bytes(self.sock.recv(4),'big')if typ == 0:l = int.from_bytes(self.sock.recv(4),'big')d = self.sock.recv(l)txt = self.decrypt_data(d).decode()self.log(f"【收到明文】{txt}")self.log(f"【收到密文】{d.hex()}\n")elif typ == 1:fnl = int.from_bytes(self.sock.recv(4),'big')fn = self.sock.recv(fnl).decode()fsz = int.from_bytes(self.sock.recv(8),'big')l = int.from_bytes(self.sock.recv(4),'big')d = self.sock.recv(l)raw = self.decrypt_data(d)with open(f"recv_{fn}",'wb') as f:f.write(raw)self.log(f"【收到文件】{fn} 已保存")self.log(f"【文件密文】{d.hex()}\n")except:self.log("服务端断开")self.connected = Falsebreakdef connect_server(self):try:self.sock = socket.socket()self.sock.connect((HOST, PORT))self.connected = Trueself.log(f"成功连接服务端 {HOST}")threading.Thread(target=self.receive_loop, daemon=True).start()except Exception as e:self.log(f"连接失败:{e}")messagebox.showerror("错误",str(e))if __name__ == "__main__":root = tk.Tk()app = ClientGUI(root)root.mainloop()

2.5分析关键代码的功能和使用方法
(1)日志显示函数

def log(self, text):self.log_area.insert(tk.END, text + "\n")**self.log_area.yview(tk.END)

功能
在界面滚动文本框中追加输出文字,自动换行并自动到最新消息位置。记录服务启动、客户端连接、收发明文密文、文件状态、报错信息。
使用方法
自动调用,不需要手动操作,所有运行信息都会自动打印在界面日志区。
(2)加解密操作
AES 加密函数

def encrypt_data(self, data):iv = get_random_bytes(16)cipher = AES.new(KEY, AES.MODE_CBC, iv)return iv + cipher.encrypt(pad(data, AES.block_size))

AES 解密函数

def decrypt_data(self, data):iv = data[:16]cipher = AES.new(KEY, AES.MODE_CBC, iv)return unpad(cipher.decrypt(data[16:]), AES.block_size)

功能
采用 AES-CBC 模式加密数据:
解密后,还原原始文本或文件二进制数据。

使用方法
程序自动调用,无需手动修改。

(3)发送文本功能函数

def send_text(self):if not self.conn:messagebox.showerror("错误", "客户端未连接")returntext = self.msg_entry.get().strip()if not text: returntry:plain = text.encode()enc = self.encrypt_data(plain)self.conn.sendall((0).to_bytes(4, 'big'))self.conn.sendall(len(enc).to_bytes(4, 'big'))self.conn.sendall(enc)self.log(f"【发送明文】{text}")self.log(f"【发送密文】{enc.hex()}\n")self.msg_entry.delete(0, tk.END)except:self.log("发送失败")

功能
获取输入框文本 → 编码 → AES 加密 → 按格式发送给客户端 → 日志打印明文和密文。
使用方法
在界面输入文字,点击即可自动完成加密发送。
(4)发送文件功能函数

def send_file(self):if not self.conn: returnpath = self.file_path.get()if not os.path.exists(path): returntry:fn = os.path.basename(path)fsize = os.path.getsize(path)with open(path, 'rb') as f:data = f.read()enc = self.encrypt_data(data)self.conn.sendall((1).to_bytes(4, 'big'))self.conn.sendall(len(fn.encode()).to_bytes(4, 'big'))self.conn.sendall(fn.encode())self.conn.sendall(fsize.to_bytes(8, 'big'))self.conn.sendall(len(enc).to_bytes(4, 'big'))self.conn.sendall(enc)self.log(f"【文件发送成功】{fn}")except:self.log("文件发送失败")

功能
读取本地文件 → 获取文件名和大小 → 二进制加密 → 按协议依次发送类型、文件名、文件大小、加密数据。
使用方法
点击选择文件 → 选中文件 → 点击发送文件,自动加密传输。(接收方收到的文件在工程目录下)

(5)接收消息与文件处理

def handle_client(self):while True:try:typ = int.from_bytes(self.conn.recv(4), 'big')if typ == 0:l = int.from_bytes(self.conn.recv(4), 'big')d = self.conn.recv(l)txt = self.decrypt_data(d).decode()self.log(f"【接收明文】{txt}")self.log(f"【接收密文】{d.hex()}\n")elif typ == 1:fnl = int.from_bytes(self.conn.recv(4), 'big')fn = self.conn.recv(fnl).decode()fsz = int.from_bytes(self.conn.recv(8), 'big')l = int.from_bytes(self.conn.recv(4), 'big')d = self.conn.recv(l)raw = self.decrypt_data(d)with open(f"recv_{fn}", 'wb') as f:f.write(raw)self.log(f"【收到文件】{fn} 已保存")self.log(f"【文件密文】{d.hex()}\n")except:self.log("客户端断开")self.conn = Nonebreak

功能
循环监听客户端数据:
类型 0:接收加密文本 → 解密 → 显示明文、密文;
类型 1:接收文件名、文件大小、加密文件数据 → 解密 → 自动保存为 recv_文件名。
使用方法
客户端连接后自动后台运行,无需手动操作,自动接收消息和文件并保存。
2.6分析生成程序的优点
LLM生成代码与我的代码对比:
(1)我的代码
ASCII 码整体偏移 3 位加密,原理简单,行数少,适合新手理解。但保密性差,且只能对普通文本加密,不能处理文件。
没有图形界面,只能在命令行输入消息、查看密文和明文,只能完成基础文字聊天。
(2)LLM生成代码
采用AES-CBC 专业加密,需要固定密钥,加密标准正规,安全程度高。
带有图形可视化界面,配有消息输入框、日志显示区域、文件选择按钮。
文字通信和文件双向传输,能自动识别文本消息和文件消息,接收的文件可自动保存。
总结:AI功能还是过于强大,专业加密方式和图形化界面也让我感到震撼,优点很多,这里就列几条主要的。

2.7运行过程和结果截图
我作服务端
2a7775967733401760121a6a80306a81

我作客户端
13843c543c7e3aa86e44a0245baf1841

收到的文本文件保存到本地
69d976da84a09ea9dfb2a3a9cbfa9bf2

同时附上队友截图

fc33a314de475af3dfaff71de9b2b528
de7925b833ecd8952709c00a672c8406
80f6a076057c14eebae865255462277e

程序代码托管到码云
仓库地址

3. 实验过程中遇到的问题和解决过程

  • 问题1:两台电脑连同一个手机热点,本机自己运行服务端和客户端可以正常通信;换成两台同学电脑互相连接,一直连接失败,提示 10061 目标计算机积极拒绝,连不上服务端。
  • 问题1解决方案:其中一台电脑,专用网络和公用网络防火墙忘记关闭;关闭后重新运行服务端和客户端,就能正常连接。
  • 问题2:复制代码到 PyCharm 运行,直接报错,提示tk(图形页面)、pycryptodome(AES加密) 模块不存在,程序打不开、运行失败。
  • 问题2解决方案:在 PyCharm 终端执行安装命令:pip install pycryptodome 。 tk本来下载安装环境的时候应该自带(但当时下载的是无线版,没有带着tk这个插件),重新下载在线版,重新给pycharm配置了新的解释器;安装完成后重启项目,代码即可正常运行。
  • 问题3:着急先点开客户端,再开服务端,一直连不上。
  • 问题3解决方案:先启动服务端,等待服务端显示启动成功后,再运行客户端。

其他(感悟、思考等)

通过这次双人网络加密通信实验,收获挺大的,也发现了自己不少问题。
以前上课只听理论,感觉网络通信挺简单,真正自己和队友联机调试,才发现实际操作难点特别多。
环境配置这块,没安装tk模块,直接导致图形界面跑不起来,耽误了不少时间。
然后就是联机通信这块,一开始两台电脑怎么都连不上,后来才知道是电脑防火墙拦着连接。还有一开始对IP地址,还把自己和队友的IP填反了,肯定连不上。
还有一些小问题,都是实际操作中才遇到的。同时我也对比了自己写的代码和LLM生成代码,能明显感觉到AI强的不是一点半点。
这次实验让我明白,python要多动手实操。遇到报错不能瞎改代码,要静下心排查原因,慢慢积累经验,才能成功。

参考资料

  • 《Java程序设计与数据结构教程(第二版)》

  • 《Java程序设计与数据结构教程(第二版)》学习指导

  • ...

http://www.jsqmd.com/news/758400/

相关文章:

  • AI 伙伴协作实验室:我的长期能力建设与证据沉淀(AILab-NOTE-20260421-01) - 玄之
  • 《R语言医学数据分析实战》学习记录|第六章 线性回归分析
  • YOLO11涨点优化:Neck二次创新 | 融合Context Aggregation Module (CAM),捕获不同感受野下的多尺度上下文信息
  • 门头招牌灯箱灯条高性价比源头工厂推荐,行业口碑汇总分享 - 品牌企业推荐师(官方)
  • MoE模型:稀疏激活架构原理与优势
  • 国产化容器迁移迫在眉睫,Docker 27引擎适配失败率下降83%的5大硬核技巧
  • 2026年必知!搬家神器缠绕膜源头厂家联系电话大揭秘 - GrowthUME
  • 2026年探秘深圳防潮蜂窝板源头工厂的惊人内幕 - GrowthUME
  • 告别LIFA:用LINX在LabVIEW里玩转Arduino,为什么我更推荐它?
  • 3步打造你的专属音乐播放器:LX Music桌面版完全指南
  • 开发者在跨平台项目中统一管理大模型 API 调用的实践
  • 2026年,这家靠谱的江西不锈钢水箱服务商凭啥脱颖而出? - 速递信息
  • 告别白屏!Electron应用启动速度优化实战:从窗口策略到Web性能的全链路提速
  • 安格尔新公司推机器宠物 Familiar:明年上市,或成宠物替代品缓解孤独
  • ProCLIP:基于LLM的渐进式视觉语言对齐框架解析
  • 观察Taotoken平台在多模型同时调用时的服务稳定性与响应表现
  • 在2026年4月亲测绍兴AI推广,这份避坑复盘值得看 - 花开富贵112
  • 拆解旧手机主板:带你认识BGA、CSP和Flip Chip这些“小黑块”
  • 武汉市精诚洁环保:汉阳水箱清洗消毒电话多少 - LYL仔仔
  • 从74LS00到74LS266:手把手教你用与非门/或非门搭建所有基础逻辑门(含电路图)
  • 1000华润万家提货券如何提到微信使用?到手多少 - 畅回收小程序
  • 从周杰伦到久石让:拆解流行与影视配乐中‘小调音阶’的实战用法与避坑指南
  • 快速验证扑克玩法:用快马AI十分钟生成‘红桃38.49’游戏可运行原型
  • Palworld存档工具终极指南:3步修复损坏存档的完整教程
  • 保研边缘人逆袭北大软微网安:我的211第一简历、套磁信与面试PPT全分享
  • 3大突破性解决方案:GroundingDINO如何用文本指令彻底改变目标检测
  • YOLO11涨点优化:特征融合改进 | 引入Zoom-in-and-out多尺度融合策略,专治极大与极小目标尺度差异显著场景
  • 手把手复现WinRAR CVE-2023-38831漏洞:从环境搭建到拿到Shell的完整实战记录
  • 想找好用的联想电脑?河南哪家经销商代理公司更靠谱? - 速递信息
  • 别乱开!Oracle补充日志(Supplemental Logging)的四种级别详解与选择指南