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

20184302 2019-2020-2 《Python程序设计》实验3报告

课程:《Python程序设计》
班级: 1843
姓名: 李新锐
学号:20184302
实验教师:王志强
实验日期:2020年5月16日
必修/选修: 公选课

1.实验内容

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

2. 实验过程及结果

导入import socket库,使得可以使用套接字的一些方法,应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。

(1)创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序;

socket(family,type[,protocol])使用给定的地址族、套接字类型、协议编号(默认为0)来创建套接字。socket.socket(socket.AF_INET,socket.SOCK_STREAM),这里使用AF_INET表示服务器之间进行网络通讯;而SOCK_STREAM表示是流式,主要是TCP面向连接的服务。这一句代码主要是用来创建TCP Socket。
s.bind(('127.0.0.1',4302))表示将套接字绑定到地址,127.0.0.1属于本地地址,4302表示使用的端口号,在AF_INET下,以元组(host,port)的形式表示地址。
s.listen()表示开始监听TCP传入连接。可在括号内指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。
conn,address = s.accept()表示接受TCP连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。
data = conn.recv(1024),在这里使用之前设立的对象conn,表示接受TCP套接字的数据。数据以字符串形式返回,1024指定要接收的最大数据量。
最后需要使用s.close()来断开连接。
在客户端也同样使用s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)和s.connect(('127.0.0.1',4302))来建立连接,其中各种符号的作用于服务器端相同。
在客户端使用了s.sendall(md.hexdigest().encode())来传送加密后的内容。完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
最后仍然需要使用s.close()来断开连接。

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

在客户端和服务器端都引入import os和import os.path文件操作的库。首先在客户端输入file=open("C:\Users\LXR\Desktop\1843\184302.txt","r")打开184302.txt文件,前面的字符串是该文件的路径,后面的r表示以只读的方式打开。
使用语句list=file.readlines()读取文件。readlines() 方法用于读取所有行(直到结束符 EOF)并返回列表。
最后使用file.close()来关闭文件。
在服务器端同样使用file=open("C:\Users\LXR\Desktop\1843\1843.txt","w+")语句来打开一个指定路径下的文件,其中的W+表示先清空文件中的原有内容再进行写入。
在服务器端增加了file.write(k)语句,表示将解密后的明文保存到上方指定路径的文件中。
最后依然使用file.close()来关闭文件。

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

对于如何加密,我们引入了import hashlib库。md = hashlib.md5()使用hashlib中的MD5加密方法进行加密,md.update(item.encode('utf-8'))进行加密,调用update函数的时候传入的值必须是编码过的,不能传Unicode字符。md.hexdigest().encode()同时使用该语句进行加密,后面的encode()表示进行客户端与服务器传输的时候必须进行编码,否则不能传输。
在服务器端,我们需要对传过来的密文进行解密,对于hash函数来说,我们不能进行反推,所以我们采用的是先列出几个可能作为明文的字符串,写出他们的hash值,最后将传过来的hash值与几个可能作为明文的字符串的hash值进行比对。使用passwds列表来保存可能作为明文的字符串。在函数make_passwd_dic中我们主要是进行hash加密运算,该函数的返回值是所有可能作为明文的字符串的加密hashlib值的列表。使用语句cryptograph=str(data.decode())将接受到客户端传过来的加密后的字符串进行解码并转化为字符串的操作。在函数break_code中我们使用k来保存可能使用到的作为明文的字符串,使用v来提取对应明文的hash值。如果发现hash值相同则将对应的明文写到文件中,则解密完成。

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

码云链接为:
服务器:https://gitee.com/li_xin_rui666/untitled1000/blob/master/实验三.py
客户端:https://gitee.com/li_xin_rui666/untitled1000/blob/master/实验三1.py

(5)实验结果截图
代码运行结果截图:

文件保存结果截图:
将客户端传送过来的密文进行解密之后保存到文件中。

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

  • 问题1:对于服务器与客户端之间的通讯过程和流程不是很清晰。
  • 问题1解决方案:可以参照下图进行分析。
  • 问题2:对于hash函数进行加密后的数据不知道如何进行破解。
  • 问题2解决方案:结合本学期学到的密码学知识,我们知道如果逆推hash函数是不可能的,所以只能使用hash函数的反查,就是将可能作为明文的hash值求出,与传入的hash值进行比对,如果相同则明文也相同。该破解方法主要是用了hash函数的值是唯一的原理。

其他(感悟、思考等)

通过此次实验使我对客户端与服务器端之间进行通讯的原理和过程以及方法有了一定深度的了解。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。同时此实验也对文件的操作进行了复习。以及我们学习到了新的知识——加密,使用hashlib库进行加密,以及对hash值进行解密的方法。使人能够综合的运用了解套接字的通讯功能。

参考资料

posted @ 2020-05-17 11:24  20184302李新锐  阅读(317)  评论(0编辑  收藏