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


1.实验内容

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

2.实验要求

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

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

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

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

3. 实验过程及结果

实验中调用了python的4个模块

  • rsa模块,进行rsa加密

设计思路

这次的实验通过2个py文件实现,分别是Server端和Cilent端。运用文件操作按行读取文件内容并进行RSA加密,最后通过socket网络编程进行加密传输并在服务端解密并保存在另一个文件里。下面放出代码(代码内有注释):

加密传输服务端

import rsa
import socket
import threading
import pickle


def write(what): #将传过来的数据写入文件中
    path = "C:\\Users\\misaka\\Desktop\\北京电子科技学院\\python\\20181221.txt"
    path = path.strip()
    path = path.rstrip("\\")
    file = open(path, 'a')
    file.write(what)
    print('写入成功')
    file.close()

def RsaDecrypt(str, pk): #rsa解密
    Decrypt_Str = rsa.decrypt(str, pk)
    Decrypt_Str_1 = Decrypt_Str.decode('utf8')
    return Decrypt_Str_1


def RecvMessage(Sock, test): #接受客户端传过来的数据
    while True:
        try:
            Message = Sock.recv(1024)
            (recvdata, PrivateKey) = pickle.loads(Message) #从bytes对象读取pickle对象层次结构并返回其中指定的重构对象层次结构。获取传入的数据和私钥
            decryptdata = RsaDecrypt(recvdata, PrivateKey)
            if len(Message) > 0: #判断数据是否接收完毕
                print("receive message:" + decryptdata)
                write(decryptdata)
        except:
            print("通信结束")
            break


def main():
    ServerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ServerSock.bind(('127.0.0.1', 1234))
    ServerSock.listen(5) #监听数量
    print("listening......") #创建连接
    while True:
        ConSock, addr = ServerSock.accept() #接收数据
        print('connection succeed' + '\n' + 'you can chat online')
        s = threading.Thread(target=RecvMessage, args=(ConSock, None)) #实例化2个Thread类,传递函数及其参数,并将线程对象放入一个列表中
        s.start()


if __name__ == '__main__':
    main()

加密传输客户端

import rsa
import socket
import threading
import pickle

def RsaEncrypt(str): #rsa加密
    (PubKey, PrivateKey) = rsa.newkeys(1024) #创建1024长度的公钥和密钥
    content = str.encode('utf8')
    Encrypt_Str = rsa.encrypt(content, PubKey)
    return (Encrypt_Str, PrivateKey)


def SendMessage(Sock, test): #读取文件数据并发送到服务端
    path = "C:\\Users\\misaka\\Desktop\\北京电子科技学院\\python\\1812\\20181221.txt" #文件路径
    path = path.strip()
    path = path.rstrip("\\")
    file = open(path, 'r')
    while 1:
        data = file.readline() #按文件行数进行读取
        if not data: #判断文件是否读完
            print('file send over...')
            break
        SendData = data
        (encryptdata, PrivateKey) = RsaEncrypt(SendData) #RSA加密
        print('encrypted data is ' + str(encryptdata))
        Message = pickle.dumps([encryptdata, PrivateKey]) #将对象的pickled表示作为bytes对象返回
        if len(SendData) > 0:
            Sock.send(Message) #发送数据
    file.close()


def main():
    ClientSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ClientSock.connect(("127.0.0.1", 1234)) #创建连接
    print('connection succeed, chat start!')
    s = threading.Thread(target=SendMessage, args=(ClientSock, None)) #实例化2个Thread类,传递函数及其参数,并将线程对象放入一个列表中
    s.start()


if __name__ == '__main__':
    main()

下面是实验运行结果:
客户端:

connection succeed, chat start!
encrypted data is b'\x9c\xf6\xd7H\xe4\xfd\xfd\xaa\xc7`\xaa)\xc6\xeb\xef\xa2\xe4\x8b\x90\xa3\xf9\xde\xda3A\xad\x9f"\x17\xd0\x0c\x97Y\x89\x95\x03\n\xb5Z\xdd"\x85(\xa4\xd3\xd7;\x91\x9f.\x0c1?\xc8\xa9U\xfcj\x0c\r\x02\x10\x81\x1e\x97\xc0\xd03d\xf71v\x05\x02\xde\x07\xa8\xc3\xc1\xf9\xc3^>\xd4\xf3\x92A\'#\xfa\x8a\xa2\xa9\xd6\x1b\xef\x0f\x19\xca\x12r\xc6y\xe4[\x7f\xdc\xce@!\xdf\x90\xa4\xb1\xe6I\x90\xc6i\xf2Z\x94w@\xfau\x11Y'
encrypted data is b'\x82\xbc_\x12\x06yc\xd2\x042\x00\x11\x06kA\xde\xd0\xd0\x18_l\x90\x90z\x17\xb9\xc3\xbf\xc5yv\xdf=\xf3\xad\xa1\x84\xb1t#\xda)N\x8e\x05*\x13W\xe0\x83\xd6\x0f\xc3\x97\x07zXN\xc8\xb9\xcf\xad\xe4\xb3\xc3\x8c\xfbI\x15R\x8b\x0b\xddI\x18l|\xdb\x8e\xe9\xcdg]b|b\xec\nP^\x05;\x14\xf3\xc8\xfb>z\xa6^\xf9U/N+c\x83\x94m\x08\xdb\xf84\x13\xe4q\x03\xa9\x97\xf0\xa5\xcd"\x15 \xc99|'
file send over...

服务端:

listening......
connection succeed
you can chat online
receive message:学号:20180001 姓名:张三 课程名称:python程序设计 成绩:100

写入成功
receive message:学号:20190002 姓名:李四 课程名称:python程序设计 成绩:98 

写入成功
通信结束

文件内容:

学号:20180001 姓名:张三 课程名称:python程序设计 成绩:100
学号:20190002 姓名:李四 课程名称:python程序设计 成绩:98

python郑晓东答案 python程序设计郑旭红_python

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

  • 问题1:由于RSA的特性,一个1024位的密钥只能加密117位字节数据,当数据量超过117位字节的时候,程序就会抛出异常。
  • 问题1解决方案:采用分多次读取的方法,避免一次读取字节数据超过117位字节。
  • 问题2:如何传输RSA的密钥和加密后数据到服务端
  • 问题2解决方案:通过百度,使用pickle.dumps函数进行传输。

其他(感悟、思考等)

由于做了之前上课时候留的加分题,这次实验难度相对来说简单一点。最重要的是有事不会问百度,百度上具有丰富的资源和信息。同时,dalao们写的各种博客也具有大量的参考价值。有时候可能看一个看不懂,但是多看几个不同的博客,有了不同的思路之后,解决问题就会相对容易起来,十分感谢愿意分享思路和方法的dalao们。说来说去,终究还是自己Python学的东西不够多,还是要有更多的学习,活到老,学到老。源代码我也已经上传到了码云