20242214 实验三《Python程序设计》实验报告
20242214 2024-2025-2 《Python程序设计》实验三报告
课程:《Python程序设计》
班级: 2422
姓名: 陈冯
学号:20242214
实验教师:王志强
实验日期:2025年4月16日
必修/选修: 公选课
一、实验内容
创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信
二、实验过程及结果
1. 创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序
- 步骤:
- 分别利用客户端和服务端的代码链接对方地址和端口
- 在终端中输入
ipconfig
查看无线局域网适配器 WLAN
中的IPv4 地址
即为所需输入的地址 - 运行代码,进行对话
- 源代码:
# 客户端
import socket
# 创建 socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
server_address = ('192.168.146.119', 1234)
client_socket.connect(server_address)
while True:
# 发送消息给服务器
message = input('请输入要发送给服务器的消息: ')
client_socket.send(message.encode('utf-8'))
# 接收服务器消息
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
print('服务器说: {}'.format(data))
# if (input("是否继续Y/N?")=="N"):
# break
# 关闭连接
client_socket.close()
# 服务端
import os
import socket
# 创建 socket 对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
server_address = ('192.168.146.120', 1234)
server_socket.bind(server_address)
# 监听连接
server_socket.listen(1)
print('服务器正在监听 {}:{}'.format(*server_address))
# 接受客户端连接
client_socket, client_address = server_socket.accept()
print('接受来自 {} 的连接'.format(client_address))
while True:
# 接收客户端消息
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
print('客户端说: {}'.format(data))
# 发送消息给客户端
message = input('请输入要发送给客户端的消息: ')
client_socket.send(message.encode('utf-8'))
if input("是否要继续?Y/N")=="N":
break
# 关闭连接
client_socket.close()
server_socket.close()
- 结果:
2. 要求包含文件的基本操作,例如打开和读写操作
- 步骤:
- 在如上代码中添加文件读写等效果。
- 源代码
# 客户端
import socket
# 创建 socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
server_address = ('192.168.146.119', 1234)
client_socket.connect(server_address)
while True:
# 发送消息给服务器
message = input('请输入要发送给服务器的消息: ')
client_socket.send(message.encode('utf-8'))
# 接收服务器消息
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
print('服务器说: {}'.format(data))
# 检测是否需要进行文件操作
if data.lower().startswith("file:"):
# 提取文件操作指令
file_command = data.split(":")[1].strip()
if file_command.startswith("read"):
# 读取文件
file_path = file_command.split()[1]
try:
with open(file_path, 'r', encoding='utf-8') as file:
file_content = file.read()
print(f"文件内容:\n{file_content}")
except FileNotFoundError:
print("文件未找到!")
except Exception as e:
print(f"读取文件时发生错误:{e}")
elif file_command.startswith("write"):
# 写入文件
file_path, content = file_command.split()[1], " ".join(file_command.split()[2:])
try:
with open(file_path, 'w', encoding='utf-8') as file:
file.write(content)
print("文件写入成功!")
except Exception as e:
print(f"写入文件时发生错误:{e}")
else:
print("未知的文件操作指令!")
# 关闭连接
client_socket.close()
# 服务端
import socket
import os
# 创建 socket 对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
server_address = ('192.168.146.120', 1234)
server_socket.bind(server_address)
# 监听连接
server_socket.listen(1)
print('服务器正在监听 {}:{}'.format(*server_address))
# 接受客户端连接
client_socket, client_address = server_socket.accept()
print('接受来自 {} 的连接'.format(client_address))
while True:
# 接收客户端消息
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
print('客户端说: {}'.format(data))
# 检测是否是文件操作指令
if data.lower().startswith("file:"):
# 提取文件操作指令
file_command = data.split(":")[1].strip()
if file_command.startswith("read"):
# 读取文件
file_path = file_command.split()[1]
try:
with open(file_path, 'r', encoding='utf-8') as file:
file_content = file.read()
response = f"文件内容:\n{file_content}"
except FileNotFoundError:
response = "文件未找到!"
except Exception as e:
response = f"读取文件时发生错误:{e}"
elif file_command.startswith("write"):
# 写入文件
file_path, content = file_command.split()[1], " ".join(file_command.split()[2:])
try:
with open(file_path, 'w', encoding='utf-8') as file:
file.write(content)
response = "文件写入成功!"
except Exception as e:
response = f"写入文件时发生错误:{e}"
else:
response = "未知的文件操作指令!"
client_socket.send(response.encode('utf-8'))
else:
# 普通消息交互
message = input('请输入要发送给客户端的消息: ')
client_socket.send(message.encode('utf-8'))
if input("是否要继续?Y/N") == "N":
break
# 关闭连接
client_socket.close()
server_socket.close()
- 结果:
- 见如下加密结果。
3. 要求发送方从文件读取内容,加密后并传输;接收方收到密文并解密,保存在文件中
- 步骤:
- 在传输文件的基础上,添加加密解密操作。
- 运行代码。
- 源代码
# 客户端
import socket
# 简单的凯撒密码加密函数
def caesar_cipher_encrypt(text, shift):
encrypted_text = []
for char in text:
if char.isalpha():
shift_amount = shift % 26
if char.islower():
new_char = chr((ord(char) - ord('a') + shift_amount) % 26 + ord('a'))
elif char.isupper():
new_char = chr((ord(char) - ord('A') + shift_amount) % 26 + ord('A'))
encrypted_text.append(new_char)
else:
encrypted_text.append(char)
return ''.join(encrypted_text)
# 创建 socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
server_address = ('192.168.146.119', 1234)
client_socket.connect(server_address)
while True:
# 发送消息给服务器
message = input('请输入要发送给服务器的消息: ')
if message.lower().startswith("file:"):
# 提取文件操作指令
file_command = message.split(":")[1].strip()
if file_command.startswith("read"):
# 读取文件
file_path = file_command.split()[1]
try:
with open(file_path, 'r', encoding='utf-8') as file:
file_content = file.read()
print(f"文件内容:\n{file_content}")
# 加密文件内容
encrypted_content = caesar_cipher_encrypt(file_content, 3)
# 发送加密内容到服务器
client_socket.send(encrypted_content.encode('utf-8'))
except FileNotFoundError:
print("文件未找到!")
except Exception as e:
print(f"读取文件时发生错误:{e}")
else:
print("未知的文件操作指令!")
else:
client_socket.send(message.encode('utf-8'))
# 接收服务器消息
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
print('服务器说: {}'.format(data))
# 关闭连接
client_socket.close()
# 服务端
import socket
# 简单的凯撒密码解密函数
def caesar_cipher_decrypt(text, shift):
decrypted_text = []
for char in text:
if char.isalpha():
shift_amount = shift % 26
if char.islower():
new_char = chr((ord(char) - ord('a') - shift_amount) % 26 + ord('a'))
elif char.isupper():
new_char = chr((ord(char) - ord('A') - shift_amount) % 26 + ord('A'))
decrypted_text.append(new_char)
else:
decrypted_text.append(char)
return ''.join(decrypted_text)
# 创建 socket 对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
server_address = ('192.168.146.120', 1234)
server_socket.bind(server_address)
# 监听连接
server_socket.listen(1)
print('服务器正在监听 {}:{}'.format(*server_address))
# 接受客户端连接
client_socket, client_address = server_socket.accept()
print('接受来自 {} 的连接'.format(client_address))
while True:
# 接收客户端消息
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
print('客户端说: {}'.format(data))
# 检测是否是加密文件内容
if data.startswith("file:"):
# 提取文件操作指令
file_command = data.split(":")[1].strip()
if file_command.startswith("write"):
# 解密文件内容
decrypted_content = caesar_cipher_decrypt(data, 3)
# 保存解密内容到文件
file_path = file_command.split()[1]
try:
with open(file_path, 'w', encoding='utf-8') as file:
file.write(decrypted_content)
print("文件写入成功!")
except Exception as e:
print(f"写入文件时发生错误:{e}")
else:
print("未知的文件操作指令!")
else:
# 普通消息交互
message = input('请输入要发送给客户端的消息: ')
client_socket.send(message.encode('utf-8'))
if input("是否要继续?Y/N") == "N":
break
# 关闭连接
client_socket.close()
server_socket.close()
- 结果:
4. 程序代码托管到码云
- 步骤:
- 在码云上创建新仓库,获取仓库URL。
- 在VScode中配置Git,初始化本地仓库,添加远程仓库。
- 提交代码到本地仓库,并推送到码云仓库。
- 命令栏输入
git add .``git commit -m "提交说明"``git push
日常提交代码 - 结果:
- 在VScode中链接码云,编写好程序后可直接拉取,上转至码云。
- 成功将工程项目代码托管到码云上,实现了版本控制和代码分享。
[https://gitee.com/cf2006/python]
5. 进阶操作
- 尝试使用樱花穿透构建隧道,实现电脑的远程链接。
- 本来是希望可以使得传输更加简易便捷,但是发现行不通,代码根本无法链接端口和地址,遂作罢。
三、实验过程中遇到的问题和解决过程
问题1:在运行时出现卡顿,难以继续的情况。
问题1解决方案:
- 在公网环境下难以运行,链接私人热点并重新查看终端,更换IP地址即可。
其他(感悟、思考等)
- 通过编写代码,让客户端和服务器能够完成文件的读取、加密、传输、解密和保存等一系列操作,这种从无到有的过程让我感到非常有成就感。尤其是当看到加密后的密文被正确传输并解密保存时,那种满足感难以言表。但是,在樱花穿透上的挫败,让我意识到,理论知识和实际应用之间存在着一定的差距。在今后的学习中,我需要更加注重将所学的理论知识应用到实际项目中,通过实践来加深理解。