20243116 2024-2025-2 《Python程序设计》实验三报告

课程:《Python程序设计》
班级:2431
姓名:陆翔轩
学号:20243116
实验教师:王志强
实验日期:2025年4月16日
必修/选修: 公选课

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

二、实验过程及结果
(一)创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序

1.查询IP地址

在cmd终端中调用ipconfig函数

2.实验代码

服务端代码:

-- coding: utf-8 --

import socket

创建 socket 对象

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

绑定地址和端口

server_address = ('192.168.232.42', 8888)
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()

客户端代码:

-- coding: utf-8 --

import socket

创建 socket 对象

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

连接到服务器

server_address = ('192.168.232.42',8888)
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()

3.运行结果截图:

服务端:

客户端:

(二)要求包含文件的基本操作,例如打开和读写操作(选做)

服务端代码:
import socket

创建 socket 对象

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

绑定地址和端口

server_address = ('192.168.232.42', 8888)
server_socket.bind(server_address)

监听连接

server_socket.listen(1)
print('服务器正在监听 {}:{}'.format(*server_address))

接受客户端连接

client_socket, client_address = server_socket.accept()
print('接受来自 {} 的连接'.format(client_address))

打开文件以记录消息

with open('server_messages.txt', 'a', encoding='utf-8') as server_file:
while True:
# 接收客户端消息
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
print('客户端说: {}'.format(data))
server_file.write(f'客户端发送: {data}\n')

      # 发送消息给客户端
      message = input('请输入要发送给客户端的消息: ')
      client_socket.send(message.encode('utf-8'))
      server_file.write(f'发送给客户端: {message}\n')
      if input("是否要继续?Y/N") == "N":
          break

关闭连接

client_socket.close()
server_socket.close()

客户端代码:
import socket

创建 socket 对象

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

连接到服务器

server_address = ('192.168.232.42', 8888)
client_socket.connect(server_address)

打开文件以记录消息

with open('client_messages.txt', 'a', encoding='utf-8') as client_file:
while True:
# 发送消息给服务器
message = input('请输入要发送给服务器的消息: ')
client_socket.send(message.encode('utf-8'))
client_file.write(f'发送给服务器: {message}\n')

      # 接收服务器消息
      data = client_socket.recv(1024).decode('utf-8')
      if not data:
          break
      print('服务器说: {}'.format(data))
      client_file.write(f'服务器回复: {data}\n')
      if input("是否继续Y/N?") == "N":
          break

关闭连接

client_socket.close()

截图:

(三)要求发送方从文件读取内容,加密后并传输;接收方收到密文并解密,保存在文件中

1.安装 pycryptodome 库

2.加密插件
import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

创建服务器套接字

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

绑定地址和端口

address = ('localhost', 9999)
server_socket.bind(address)

开始监听

server_socket.listen()
print("服务器正在监听端口 9999...")

try:
# 接收客户端连接
conn, addr = server_socket.accept()

  # 接收加密数据
  encrypted_data = conn.recv(4096)  # 根据需要调整接收缓冲区大小
  print("接收到加密数据,开始解密...")

  # AES 加密参数
  key = b'1234567890987654'  # 16 字节密钥
  iv = b'1234567890987654'  # 初始化向量

  # 创建 AES 解密器
  cipher = AES.new(key, AES.MODE_CBC, iv=iv)
  decrypted_data = cipher.decrypt(encrypted_data)

  # 去除填充
  try:
      decrypted_data = unpad(decrypted_data, AES.block_size)
  except ValueError as e:
      print(f"解密失败:{e}")
      decrypted_data = "解密失败".encode("utf-8")  # 使用 UTF-8 编码将字符串转换为 bytes

  # 保存解密后的数据到文件
  with open("decrypted_output.txt", "wb") as f:
      f.write(decrypted_data)

  print("解密完成,数据已保存到 decrypted_output.txt")

finally:
# 关闭服务器套接字
server_socket.close()

客户端代码:
import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

try:
# 创建客户端套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  # 定义服务器地址和端口
  server_address = ('localhost', 9999)

  # 连接到服务器
  client_socket.connect(server_address)
  print("已连接到服务器")

  # AES 加密参数
  key = b'1234567890987654'  # 16 字节密钥
  iv = b'1234567890987654'  # 初始化向量

  # 读取文件内容
  with open("decrypted_input.txt", "rb") as f:
      data = f.read()

  # 创建 AES 加密器
  cipher = AES.new(key, AES.MODE_CBC, iv=iv)

  # 对数据进行加密,确保数据长度是块大小的倍数
  padded_data = pad(data, AES.block_size)
  encrypted_data = cipher.encrypt(padded_data)

  # 发送加密数据
  client_socket.sendall(encrypted_data)
  print("加密数据已发送到服务器")

except socket.error as e:
print(f"套接字错误: {e}")
except FileNotFoundError:
print("文件未找到")
except Exception as e:
print(f"发生其他错误: {e}")
finally:
# 关闭客户端套接字
client_socket.close()

截图:

(四)程序代码托管到码云

三、 实验过程中遇到的问题和解决过程
问题1:安装不了pycryptodome库

解决方案:改用异或加密
服务端代码:
import socket

创建服务器套接字

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

绑定地址和端口

address = ('192.168.232.42', 9999)
server_socket.bind(address)

开始监听

server_socket.listen()
print("服务器正在监听端口 9999...")

try:
# 接收客户端连接
conn, addr = server_socket.accept()

# 接收加密数据
encrypted_data = conn.recv(4096)  # 根据需要调整接收缓冲区大小
print("接收到加密数据,开始解密...")

# 异或加密密钥
key = b'1234567890987654'

# 异或解密
decrypted_data = bytes([encrypted_data[i] ^ key[i % len(key)] for i in range(len(encrypted_data))])

# 保存解密后的数据到文件
with open("decrypted_output.txt", "wb") as f:
    f.write(decrypted_data)

print("解密完成,数据已保存到 decrypted_output.txt")

finally:
# 关闭服务器套接字
server_socket.close()

客户端代码:
import socket

尝试创建 decrypted_input.txt 文件

try:
with open('decrypted_input.txt', 'w') as f:
pass
except Exception as e:
print(f"创建文件失败,原因:{e}")

try:
# 创建客户端套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 定义服务器地址和端口
server_address = ('192.168.232.42', 9999)

# 连接到服务器
client_socket.connect(server_address)
print("已连接到服务器")

# 异或加密密钥
key = b'1234567890987654'

# 读取文件内容
with open("decrypted_input.txt", "rb") as f:
    data = f.read()

# 异或加密
encrypted_data = bytes([data[i] ^ key[i % len(key)] for i in range(len(data))])

# 发送加密数据
client_socket.sendall(encrypted_data)
print("加密数据已发送到服务器")

except socket.error as e:
print(f"套接字错误: {e}")
except FileNotFoundError:
print("文件未找到")
except Exception as e:
print(f"发生其他错误: {e}")
finally:
# 关闭客户端套接字
client_socket.close()

运行结果截图:


四、其他(感悟、思考等)
1.pip 无法使用,只能从csdn上面找资料并且实践了

2.复制地址的时候别把空格复制进去了,不然无法运行

参考资料
《python3.7安装pycryto或者pycryptodome的方法(全网最快最简单)》(小笨聪)

posted @ 2025-04-23 12:35  20243116探玥  阅读(32)  评论(0)    收藏  举报