20244319 实验三《Python程序设计》实验报告

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

课程:《Python程序设计》
班级:2443
姓名:梁悦
学号:20244319
实验教师:王志强
实验日期:2025年4月16日
必修/选修: 公选课

一、实验内容

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

二、实验过程及结果

(一)创建服务端和客户端,

1.查询IP地址

在cmd终端中调用ipconfig函数(此处查询的是搭档的IP地址)

2.实验代码

服务端代码:

点击查看代码
# -*- coding: utf-8 -*-

      import socket

      # 创建 socket 对象
      server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

      # 绑定地址和端口
      server_address = ('192.168.43.159', 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.10.48',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.运行结果截图:

服务端(此处搭档已连接我的热点,故其ip地址为196.168.43.120):

客户端:

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

服务端代码:

点击查看代码
import socket

      # 创建 socket 对象
      server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

      # 绑定地址和端口
      server_address = ('192.168.43.159', 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.10.48', 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库
  • 问题1解决方案:改用异或加密

服务端代码:

点击查看代码
import socket

      # 创建服务器套接字
      server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

      # 绑定地址和端口
      address = ('192.168.43.159', 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.10.48', 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.机魂不悦,无法战胜(拜orz);

2.要搞清楚服务端IP是哪个,不然无法建立连接(SOS ;

3.学会了如何折叠代码,开心~~。

参考资料

  • 《零基础学Python》(2018 明日科技编著)
posted @ 2025-04-21 13:15  20244319梁悦  阅读(48)  评论(0)    收藏  举报