zoukankan      html  css  js  c++  java
  • 20181218 实验三《Python程序设计》实验报告

    20181218 2019-2020-2 《Python程序设计》实验三报告

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

    1.实验内容

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

    2. 实验过程及结果

    实现服务端和客户端通信

    这一部分之前在课程中已经能够实现。但是只能实现本机通信,我尝试与另一位同学实现远程通信,最终成功的方法是使用他租赁的服务器。
    服务端代码:

    import socket
    # 服务器端的socket初始化
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # arg1:服务器之间网络通信;arg2:流式socket,for TCP
    s.bind(('127.0.0.1',8081)) # 绑定,port:0-65535
    
    s.listen() # 监听
    conn,address = s.accept()
    data = conn.recv(1024) # 接收客户端发送数据的时候不可以用s.recv()
    print(data.decode())
    conn.sendall(('服务器已经接收到了数据内容:'+str(data.decode())).encode())
    s.close()
    

    客户端代码:

    import socket
    # 客户端的socket初始化
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # arg1:服务器之间网络通信;arg2:流式socket,for TCP
    s.connect(('127.0.0.1',8081)) # 连接,元祖的形式(ip地址,端口)
    # 发送数据
    str = input('请输入要传输的内容:')
    s.sendall(str.encode())
    # 接收数据
    data = s.recv(1024) # arg:接收大小
    print(data.decode())
    # 关闭套接字
    s.close()
    

    以上代码只能实现一次通信,为了可以传递多条信息,添加while循环。注意服务端需要两个循环嵌套。
    服务端代码:

    import socket
    # 服务器端的socket初始化
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # arg1:服务器之间网络通信;arg2:流式socket,for TCP
    s.bind(('127.0.0.1',8081)) # 绑定,port:0-65535
    
    s.listen() # 监听
    while(1):
        conn,address = s.accept()
        while(1):    
            data = conn.recv(1024) # 接收客户端发送数据的时候不可以用s.recv()
            print(data.decode())
            conn.sendall(('服务器已经接收到了数据内容:'+str(data.decode())).encode())
    s.close()
    

    客户端代码:

    import socket
    # 客户端的socket初始化
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # arg1:服务器之间网络通信;arg2:流式socket,for TCP
    s.connect(('127.0.0.1',8081)) # 连接,元祖的形式(ip地址,端口)
    while(1):
        # 发送数据
        str = input('请输入要传输的内容:')
        s.sendall(str.encode())
        # 接收数据
        data = s.recv(1024) # arg:接收大小
        print(data.decode())
    # 关闭套接字
    s.close()
    

    文件的读写

    with open帮助我们自动关闭文件。f.read()f.write()方法可以轻松读写整个文件的内容,保存在一个字符串中,注意与传输中二进制格式的转换即可。客户端只需要以r模式打开文件并读取文件内容,可以读取多个文件的内容,依次传输给服务端;服务端初始时以w模式打开待写入的文件,清空里面的内容,然后通信开始后,每次传输时以a模式打开待写入文件,这样就可以把每次通信传输的内容都保存下来。
    服务端代码:

    import socket
    
    # 服务器端的socket初始化
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # arg1:服务器之间网络通信;arg2:流式socket,for TCP
    s.bind(('127.0.0.1',8081)) # 绑定,port:0-65535
    
    s.listen() # 监听
    # 新建并清空用于服务端存储信息的文件
    with open('server_got.txt', 'w') as f:
        pass
    while 1:
        conn,address = s.accept()
        while 1:
            data = conn.recv(1024) # 接收客户端发送数据的时候不可以用s.recv()
            print(data.decode())
            # 将收到并解密后的数据写入文件
            with open('server_got.txt', 'a') as f:
                f.write(data.decode())
                f.close()
            conn.sendall(('服务器已经接收到了数据内容:'+str(data.decode())).encode())
    s.close()
    

    客户端代码:

    import socket
    from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT
    
    # 客户端的socket初始化
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # arg1:服务器之间网络通信;arg2:流式socket,for TCP
    s.connect(('127.0.0.1',8081)) # 连接,元祖的形式(ip地址,端口)
    while 1:
        # 从文件读取数据
        fp = input('请输入要传输的文件名:')
        with open(fp, 'r') as f:
            str  = f.read()
        # 发送数据
        s.sendall(str.encode())
        # 接收数据
        data = s.recv(1024) # arg:接收大小
        print(data.decode())
    # 关闭套接字
    s.close()
    

    加密和解密

    这里我使用的是SM4算法,对称加密和解密。注意bytes类型即可。
    服务端代码:

    import socket
    from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT
    
    # 服务器端的socket初始化
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # arg1:服务器之间网络通信;arg2:流式socket,for TCP
    s.bind(('127.0.0.1',8081)) # 绑定,port:0-65535
    
    s.listen() # 监听
    # 新建并清空用于服务端存储信息的文件
    with open('server_got.txt', 'w') as f:
        pass
    while 1:
        conn,address = s.accept()
        while 1:
            data = conn.recv(1024) # 接收客户端发送数据的时候不可以用s.recv()
            # 解密
            key = b'3l5butlj26hvv313'
            crypt_sm4 = CryptSM4()
            crypt_sm4.set_key(key, SM4_DECRYPT)
            decrypt_value = crypt_sm4.crypt_ecb(data)  # bytes类型
    
            print(decrypt_value.decode())
            # 将收到并解密后的数据写入文件
            with open('server_got.txt', 'a') as f:
                f.write(decrypt_value.decode())
                f.close()
            conn.sendall(('服务器已经接收到了数据内容:'+str(decrypt_value.decode())).encode())
    s.close()
    

    客户端代码:

    import socket
    from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT
    
    # 客户端的socket初始化
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # arg1:服务器之间网络通信;arg2:流式socket,for TCP
    s.connect(('127.0.0.1',8081)) # 连接,元祖的形式(ip地址,端口)
    while 1:
        # 从文件读取数据
        fp = input('请输入要传输的文件名:')
        with open(fp, 'r') as f:
            str  = f.read()
        # 加密
        key = b'3l5butlj26hvv313'
        value = str.encode()
        crypt_sm4 = CryptSM4()
        crypt_sm4.set_key(key, SM4_ENCRYPT)
        encrypt_value = crypt_sm4.crypt_ecb(value)  # bytes类型
        # 发送数据
        s.sendall(encrypt_value)
        # 接收数据
        data = s.recv(1024) # arg:接收大小
        print(data.decode())
    # 关闭套接字
    s.close()
    

    运行测试

    首先启动server代码,然后启动client代码。
    在client端输入要传输的文件路径和文件名(这里测试时进行了两次循环,依次传输了exp3.txt和test.txt两个文件),服务端读取文件数据后加密并传输给服务端

    服务端依次收到并解密,写入文件

    客户端读取的两个文件内容如下:

    服务端写入后的文件内容如下:

    码云链接

    Server端代码
    Client端代码

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

    无。

    其他(感悟、思考等)

    Python可以非常简洁地实现通信,很好。

    参考资料

    Python 读写文件
    支持国密算法的 Python 加密包 gmssl-python

  • 相关阅读:
    【Python进阶】用 Python 统计字数
    【Python进阶】无论API怎么变,SDK都可以根据URL实现完全动态的调用
    【机器学习_吴恩达_笔记】(一)机器学习的动机和应用
    【Python入门总结】
    【Python入门学习】列表生成和函数生成器的方式实现杨辉三角
    【Python入门学习】闭包&装饰器&开放封闭原则
    【Pthon入门学习】利用slice实现str的strip函数,类似C#中的string.trim
    【Pthon入门学习】99乘法表
    【Pthon入门学习】多级菜单小例子
    要素图层范围查询属性arcgis api for js(featuretable根据上篇的优化)原创
  • 原文地址:https://www.cnblogs.com/hardcoreYutian/p/12900789.html
Copyright © 2011-2022 走看看