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

20193415 2020-2021-2 《Python程序设计》实验三报告

课程:《Python程序设计》
班级: 1934
姓名: 简文翔
学号: 20193415
实验教师:王志强
实验日期:2021年5月24日
必修/选修:公选课

1. 实验内容

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

2. 实验过程及结果

(1) 创建服务端

  1. 创建套接字,绑定套接字到本地IP与端口

    # 参数1:服务器之间网络通信;参数2:流式socket, for TCP
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定:localhost = 127.0.0.1, port = 33624
    s.bind(('127.0.0.1', 33624))
    
  2. 开始监听连接并接受客户端的请求

    要求服务端在特定端口监听多个客户请求,故设置listen()的参数为5
    (在拒绝连接之前,操作系统可以挂起的最大连接数量为5)

    s.listen(5)
    conn, address = s.accept()
    
  3. 接收传来的数据,并发送给对方数据

    data = conn.recv(1024)  # 接受套接字的数据,最大数据量为1024
    print(data.decode("utf-8"))
    conn.sendall(("服务端接收到了数据:" + str(data.decode("utf-8"))).encode("utf-8"))
    
  4. 将接受到的数据解密并写入txt文件,关闭套接字

    f = open("Server.txt", 'w', encoding="utf-8")
    f.write((base64.b64decode(data).decode("ascii")))
    s.close()
    

(2) 创建客户端

  1. 创建套接字,连接远端地址

    # 参数1:服务器之间网络通信;参数2:流式socket, for TCP
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('127.0.0.1', 33624))
    
  2. 打开txt文件读取内容并进行base64加密

    f = open("Client.txt", 'r', encoding="utf-8")
    message = f.read()
    print("加密后的数据为:" + str(base64.b64encode(message.encode("utf-8"))))
    

    首先,从“Client.txt”文件中读取的数据是字符串,而base64.b64encode()加密函数的参数是字节流,故调用encode("utf-8")将读取的数据转化为字节流;
    经base64.b64encode()加密后的数据变为字节流,不能直接与字符串一同被print,故利用str()转化为字符串

  3. 连接后发送数据和接收数据,关闭套接字

    s.sendall(base64.b64encode(message.encode("utf-8")))  # 发送加密数据
    data = s.recv(1024)
    print(data.decode())
    s.close()
    

(3) 实验结果

  • 客户端能够正常收到服务端数据,且服务端收到的数据正确

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

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

  • 问题1:报错:应为类型'bytes',但得到的是'str'

    解决方案:conn.sendall()函数的参数必须是字节流,应该用bytes()转化

  • 问题2:报错:由于目标计算机积极拒绝,无法连接

    解决方案:往往出现于报错后修改完代码再次运行,重启Pycharm后即可正常运行

  • 问题3:报错:string argument without an encoding

    解决方案:顾名思义,第20行中的str(Plaintext)改为str(Plaintext).encode("utf-8")

其他(感悟、思考等)

  本次实验是利用Socket编程技术实现服务端与客户端的通信过程,对我来说都是很新奇的知识。实验的代码倒不难写,但是里面的通信过程是非常具有典型性的,能够掌握这样一种通信的过程对我来说是非常有帮助。在编写简简单单的一句conn.sendall(("服务端接收到了数据:" + str(data.decode("utf-8"))).encode("utf-8"))时,我也是进行了非常多次的尝试才使它不报错,这使我对函数的参数与输出的数据编码有了深层次的理解。

参考资料

posted @ 2021-05-29 22:10  Lezs  阅读(163)  评论(0编辑  收藏  举报