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

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

课程:《Python程序设计》
班级: 2421
姓名: 邹清楠
学号:20242126
实验教师:王志强
实验日期:2025年4月16日
必修/选修: 公选课

一. 实验内容

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

二. 实验过程及结果

1.服务端部分

(1) 导入os库和socket库

import socket
import os

(2)定义加密函数

这里使用了异或加密,仅为对文本进行加密的一个示例。当然也可以使用其他的加密方法。

def xor(data, key):
    #确保数据为byte类型
    if isinstance(data, str):
        dabin = data.encode('utf-8')
    else:
        dabin = data
    kebin = key.encode('utf-8')
    result = bytearray()
    length = len(kebin)
    #循环用密钥加密数据并存入reslut
    #这样一来,当密钥比数据短时仍然可以加密
    for i, byte in enumerate(dabin):
        result.append(byte ^ kebin[i % length])
    return bytes(result)
    # 根据输入类型决定返回类型
    return result.decode('utf-8', errors='ignore') if isinstance(data, str) else bytes(result)

(3)基本配置环节

key = "NORREICH" #定义密钥
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建TCP套接字
server.bind(('localhost', 9999)) #绑定IP和端口,这里用了本机的IP
server.listen(5)
print("服务器已启动,监听中...")

(4)主体部分

主题部分使用try语句,方便记录异常情况

try:
    while True: #进入循环,不断进行两端的信息发送
        client, address = server.accept()
        # 接受客户端连接,返回客户端socket对象和地址信息
        print(f"客户端 {address} 已连接") # 打印客户端连接信息
        
        try:
            proc_data = client.recv(1024) #接受最多1024字节的信息
            if not proc_data: #收到空数据则跳过
                continue
            #对数据进行加密
            deproc_data = xor(proc_data, key).decode('utf-8', errors='ignore')
            
            if deproc_data.startswith("FILE"): #当客户端发送FILE开头的文本时,则开始接收文件
                filename = deproc_data[4:].strip() #切割获得文件名
                save = os.path.join("D:\\Temp", filename) #构造文件保存路径,这里预先填好了一个
                print(f"FILE命令识别成功,开始接收文件 {filename}")
                #以二进制写入模式打开文件(其实是创建了一个新文件)
                with open(save, 'wb') as f:
                    while True:
                        chunk = client.recv(4096)
                        if not chunk:
                            break
                        de_chunk = xor(chunk, key)
                        # 检查是否收到结束标记
                        try:
                            if de_chunk.decode('utf-8') == "EOF":
                                break
                        except:
                            pass
                        #将数据写入文件
                        f.write(de_chunk)
                
                print("文件接收完成")
                response = xor("服务器回应:文件接受成功!", key)
                client.send(response)
                
            else:#普通消息
                print(f"客户端消息: {deproc_data}")
                response2 = input("请输入向客户端发送的消息:")
                response = xor(response2, key)
                client.send(response)
                
        except Exception as e:
            #捕获并打印异常信息
            print(f"发生错误:{e}")
        finally:
            client.close()
            
except KeyboardInterrupt:
    print("服务器关闭")
finally:
    server.close()

2.客户端部分

客户段部分与服务器端相差不大,主要区别在主体部分

if user.upper().startswith("FILE"):#开始传输文件
            filename = user[4:].strip()
            path = os.path.join("D:\\Temp\\Multiwheel", filename)
            
            if not os.path.exists(path):
                print(f"文件不存在:{filename}")
                continue
                
            # 发送文件头信息
            head = f"FILE{filename}"
            de_head = xor(head, key)
            client.send(de_head)
            
            print(f"开始发送文件:{filename}")
            with open(path, 'rb') as f:
                #以二进制只读模式打开文件
                while True:
                    data = f.read(4096)
                    if not data:
                        # 发送结束标记
                        client.send(xor("EOF", key))
                        break
                    de_data = xor(data, key)
                    client.send(de_data)
            
            print("文件发送完成")
            # 等待服务器确认
            enc = client.recv(1024)
            response = xor(enc, key).decode('utf-8')
            print(f"服务器响应: {response}")

以下是运行截图:
首先我在客户端的预定目录里存放了一个叫1.txt的文本文档

然后,开启服务端和客户端

在客户端中输入“FILE1.txt”,客户端接到命令传输文件,服务端显示接受成功

进入服务端的保存路径,果然有文件存在

接下来进行普通消息传输测试:


确保两台电脑同时连接同一个WIFI,在cmd中运行ipconfig命令,将程序中的IPv4地址换为WIFI的

一台电脑先运行服务端,另一台电脑运行客户端,传输消息成功

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

  • 问题1:服务端一直显示监听中,无法对数据做出反应
    问题1解决方案:在之前已经使用了server.accept(),使得端口被占据,删掉代码即可

  • 问题2:有时两端连接之后,服务端无法显示任何内容
    问题2解决方案:显示问题,其实可以进行操作,重新进入后可以在历史记录中看到记录

  • 问题3:运行客户端时显示“由于目标计算机积极拒绝,无法连接。”
    问题3解决方案:确保服务端已经在运行,然后再运行客户端

4.感悟和思考

  • 通过这次实验,我学会了使用try语句,用try语句写出的代码更加稳定可靠。对于文件传输,还可以使其更为人性化,比如可以从用户输出里获取文件发送和保存路径。最后,我没有添加退出功能,只能强制退出,应当改进。

参考资料

posted @ 2025-04-22 18:16  Norreich  阅读(51)  评论(0)    收藏  举报