20253320蒋丰任实验三 Socket编程技术

学号 2025-2026-2 《Python程序设计》实验x报告

课程:《Python程序设计》
班级:2533
姓名: 蒋丰任
学号:20253320
实验教师:王志强
实验日期:2026年4月27日
必修/选修: 公选课

1.实验内容

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

2. 实验过程及结果

1.我作为服务端:(已经先进行了加密,发出去以后再用同样的密码方式进行解密)

# -*- coding: utf-8 -*-
# 文件名: EncryptedServer.py
# 学  号: 20253320 (IP已手动设为 172.20.10.20)

import socket

# --- 保持一致的加解密算法 ---
SHIFT = 5


def encrypt(text): return "".join(chr((ord(c) + SHIFT) % 0x110000) for c in text)


def decrypt(text): return "".join(chr((ord(c) - SHIFT) % 0x110000) for c in text)


# --- Server 初始化 ---
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 即使你改了本机 IP,这里依然用 0.0.0.0 效果最好,它会自动监听你那个 10.7 的地址
HOST = "172.20.10.20"
PORT = 3320

# 防止端口冲突:如果运行报错,请尝试将 4444 改为 5555
server.bind((HOST, PORT))
server.listen(1)

print("-" * 50)
print(f"学号:20253320 的安全加密服务端已启动")
print(f"请告知同桌,连接 IP 为:172.20.10.20")
print("-" * 50)

conn, addr = server.accept()
print(f"【连接成功】对方 IP 地址为:{addr}")

while True:
    try:
        # 接收并解密
        encrypted_data = conn.recv(1024).decode("utf-8")
        if not encrypted_data or encrypted_data == encrypt("exit"):
            print("对方已断开连接")
            break

        data = decrypt(encrypted_data)
        print(f"\n[收到密文] {encrypted_data}")
        print(f"客户端明文:{data}")

        # 回复并加密
        send_msg = input("回个话:")
        encrypted_msg = encrypt(send_msg)
        conn.send(encrypted_msg.encode("utf-8"))
        print(f"[发送密文] {encrypted_msg}")

        if send_msg == "exit":
            break
    except ConnectionResetError:
        print("连接被强行关闭")
        break

conn.close()
server.close()

image
2.我是客户端(输入明文→加密→发送密文,接收服务端密文→解密→打印明文)

# -*- coding: utf-8 -*-
# 文件名: EncryptedClient.py
# 描  述: 加密通信客户端
# 目标服务端: 172.20.10.7 (学号 20253407 的电脑)

import socket

SHIFT = 5


def encrypt(text):

    return "".join(chr((ord(c) + SHIFT) % 0x110000) for c in text)


def decrypt(text):

    return "".join(chr((ord(c) - SHIFT) % 0x110000) for c in text)

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

HOST = "172.20.10.7"
PORT = 3407

try:
    print(f"正在尝试连接到同学 (20253407) 的服务端...")
    client.connect((HOST, PORT))
    print(f"✅ 连接成功!现在发送的消息都会经过加密处理。")

    while True:

        send_msg = input("\n我 (明文):")
        if not send_msg:
            continue

        encrypted_send = encrypt(send_msg)
        print(f"[加密后发送] {encrypted_send}")
        client.send(encrypted_send.encode("utf-8"))

        if send_msg == "exit":
            print("退出聊天")
            break


        print("等待对方回复...")
        encrypted_data = client.recv(1024).decode("utf-8")
        if not encrypted_data:
            break

        data = decrypt(encrypted_data)
        print(f"[收到密文] {encrypted_data}")
        print(f"对方明文:{data}")

        if data == "exit":
            print("对方已下线")
            break

except Exception as e:
    print(f"❌ 连接失败!原因: {e}")
    print("排查建议:")
    print("1. 检查服务端 (172.20.10.7) 是否已经运行。")
    print("2. 检查服务端电脑的防火墙是否已关闭。")
    print("3. 确保你们连在同一个手机热点上。")

finally:
    client.close()

3152707426d865ba45fbfa8f454a9196
3.程序代码托管到码云。
image
image
4.使用LLM生成一个带图形界面的程序
(1)服务端

import socket
import threading
import tkinter as tk
from tkinter import scrolledtext, Entry, Button, Label

# 加密解密配置(对称加密,偏移量5)
SHIFT = 5

def encrypt(text):
    return ''.join(chr((ord(c) + SHIFT) % 0x110000) for c in text)

def decrypt(text):
    return ''.join(chr((ord(c) - SHIFT) % 0x110000) for c in text)

# 服务端GUI类
class ServerGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("加密通信服务端 GUI")
        self.root.geometry("650x550")

        # IP端口设置
        Label(root, text="监听端口:").place(x=20, y=20)
        self.port_entry = Entry(root)
        self.port_entry.place(x=100, y=20)
        self.port_entry.insert(0, "3407")

        # 启动按钮
        self.start_btn = Button(root, text="启动服务", command=self.start_server)
        self.start_btn.place(x=250, y=15)

        # 消息显示框
        self.show_area = scrolledtext.ScrolledText(root, width=75, height=25)
        self.show_area.place(x=20, y=60)
        self.show_area.insert(tk.END, "=== 加密通信服务端已就绪 ===\n")

        # 发送消息输入框
        Label(root, text="输入消息:").place(x=20, y=480)
        self.send_entry = Entry(root, width=40)
        self.send_entry.place(x=100, y=480)

        # 发送按钮
        self.send_btn = Button(root, text="加密发送", command=self.send_msg)
        self.send_btn.place(x=450, y=475)

        self.conn = None
        self.server_socket = None

    # 启动服务
    def start_server(self):
        port = int(self.port_entry.get())
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server_socket.bind(('0.0.0.0', port))
        self.server_socket.listen(1)
        self.show_area.insert(tk.END, f"服务已启动,监听端口:{port}\n等待客户端连接...\n")

        # 线程接收连接
        threading.Thread(target=self.accept_conn, daemon=True).start()

    # 接受客户端连接(修复:添加了冒号)
    def accept_conn(self):
        self.conn, addr = self.server_socket.accept()
        self.show_area.insert(tk.END, f"客户端已连接:{addr}\n")
        threading.Thread(target=self.recv_msg, daemon=True).start()

    # 接收消息
    def recv_msg(self):
        while True:
            try:
                data = self.conn.recv(1024).decode('utf-8')
                if not data:
                    break
                plain = decrypt(data)
                self.show_area.insert(tk.END, f"\n【接收密文】{data}\n【解密明文】{plain}\n")
            except Exception as e:
                self.show_area.insert(tk.END, "客户端断开连接\n")
                break

    # 发送消息
    def send_msg(self):
        msg = self.send_entry.get()
        if not msg or not self.conn:
            return
        cipher = encrypt(msg)
        self.conn.send(cipher.encode('utf-8'))
        self.show_area.insert(tk.END, f"\n【发送明文】{msg}\n【发送密文】{cipher}\n")
        self.send_entry.delete(0, tk.END)

# 运行
if __name__ == "__main__":
    root = tk.Tk()
    app = ServerGUI(root)
    root.mainloop()

(2)客户端

import socket
import threading
import tkinter as tk
from tkinter import scrolledtext, Entry, Button, Label

# 加密解密配置(和服务端必须完全一致!)
SHIFT = 5

def encrypt(text):
    return ''.join(chr((ord(c) + SHIFT) % 0x110000) for c in text)

def decrypt(text):
    return ''.join(chr((ord(c) - SHIFT) % 0x110000) for c in text)

# 客户端GUI类
class ClientGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("加密通信客户端 GUI")
        self.root.geometry("650x550")

        # 1. IP和端口输入区
        Label(root, text="服务端IP:").place(x=20, y=20)
        self.ip_entry = Entry(root)
        self.ip_entry.place(x=100, y=20)
        self.ip_entry.insert(0, "127.0.0.1")

        Label(root, text="端口:").place(x=280, y=20)
        self.port_entry = Entry(root, width=10)
        self.port_entry.place(x=320, y=20)
        self.port_entry.insert(0, "3407")

        # 连接按钮
        self.connect_btn = Button(root, text="连接服务端", command=self.connect_server)
        self.connect_btn.place(x=450, y=15)

        # 2. 消息显示区
        self.show_area = scrolledtext.ScrolledText(root, width=75, height=25)
        self.show_area.place(x=20, y=60)
        self.show_area.insert(tk.END, "=== 加密通信客户端已就绪 ===\n")

        # 3. 发送消息区
        Label(root, text="输入消息:").place(x=20, y=480)
        self.send_entry = Entry(root, width=40)
        self.send_entry.place(x=100, y=480)

        self.send_btn = Button(root, text="加密发送", command=self.send_msg)
        self.send_btn.place(x=450, y=475)

        # 初始化socket
        self.client_socket = None

    # 连接服务端
    def connect_server(self):
        ip = self.ip_entry.get()
        port = int(self.port_entry.get())
        self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            self.client_socket.connect((ip, port))
            self.show_area.insert(tk.END, "✅ 成功连接服务端!\n")
            # 启动接收消息线程
            threading.Thread(target=self.recv_msg, daemon=True).start()
        except Exception as e:
            self.show_area.insert(tk.END, f"❌ 连接失败:{e}\n")

    # 接收消息线程
    def recv_msg(self):
        while True:
            try:
                data = self.client_socket.recv(1024).decode('utf-8')
                if not data:
                    break
                plain = decrypt(data)
                self.show_area.insert(tk.END, f"\n【收到密文】{data}\n【解密明文】{plain}\n")
            except:
                self.show_area.insert(tk.END, "⚠️ 服务端已断开连接\n")
                break

    # 发送消息
    def send_msg(self):
        msg = self.send_entry.get()
        if not msg or not self.client_socket:
            return
        cipher = encrypt(msg)
        self.client_socket.send(cipher.encode('utf-8'))
        self.show_area.insert(tk.END, f"\n【发送明文】{msg}\n【发送密文】{cipher}\n")
        self.send_entry.delete(0, tk.END)

# 启动客户端GUI
if __name__ == "__main__":
    root = tk.Tk()
    app = ClientGUI(root)
    root.mainloop()

image
5.
(1)关键代码功能与使用方法
加密解密代码:实现对称凯撒加密,发送加密、接收解密,两端偏移量必须一致。
Socket 代码:实现 TCP 可靠通信,服务端监听端口,客户端连接 IP 和端口。
多线程代码:保证图形界面不卡顿,后台持续接收消息。
GUI 代码:提供可视化操作界面,用于输入、显示、按钮交互。
(2)程序优点
界面友好,操作简单;
明文密文同步显示;
加密传输更安全;
通信稳定不卡顿;
跨平台、无需额外库;
代码简洁易理解;
支持双向实时聊天。
6.程序代码托管到码云。
image
image

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

  • 问题1:原本我作为服务端他作为客户端可以用的,但是当改了一下IP地址整个程序就用不了
  • 问题1解决方案:换了一台电脑
  • 问题2:同样的两个代码同样的改了IP地址但是换了一下电脑就用不了了
  • 问题2解决方案:发现是热点连错了
  • 问题3:多次尝试,原本可以连得上的代码再试两遍又连不上了
  • 问题3解决方案:重启pycharm
  • 问题4:托管代码失败
  • 问题4解决方案:把提交目录当成push搞忘记了

其他(感悟、思考等)

好难,不过好神奇

参考资料

posted @ 2026-04-27 22:55  蒋丰任  阅读(13)  评论(2)    收藏  举报