借助Socket达成数据沟通及文件上传下载

2个月前发布 gsjqwyl
19 0 0

实验介绍:

利用Python编写代码来实现服务器的三项功能,分别是信息的交互、文件的上传以及文件的下载。客户端输入数字1,可进入信息交互功能;输入数字2,进入文件上传功能;输入数字3,进入文件下载功能。输入字母q则结束服务。文件的上传与下载路径由客户端自行手动输入。需先运行服务器端程序,再运行客户端程序。

代码如下

client端代码:

import socket  # 用于实现网络通信相关功能

ip_port = ('127.0.0.1', 8088)  # 定义服务器的地址和端口,这样设置方便后续修改参数

if __name__ == '__main__':  # 当该Python文件被直接执行时,__name__的值会是'__main__';若被其他模块导入,__name__的值会是模块名
    cl = socket.socket()  # 实例化socket对象,cl就像是根据图纸定制的一辆汽车,socket.socket()则是汽车的图纸
    cl.connect(ip_port)  # 传入之前定义的服务器地址和端口进行连接
    choice = input("请输入操作选项(1:信息交互,2:文件上传,3:文件下载):")  # 进行文字交互获取用户选择

    if choice == '1':
        cl.send(b'1')  # 向服务器发送字节串b'1',告知服务器客户端选择信息交互功能
        data = cl.recv(1024)  # 接收服务器返回的最多1024字节的数据
        print(data.decode())  # 打印解码后的服务器初始响应信息
        while True:  # 进入循环,持续进行信息交互
            msg_cl = input('要发送的信息:').encode()  # 获取用户输入的信息并编码
            cl.send(msg_cl)  # 将用户输入的信息发送给服务器端
            if msg_cl == b'quit' or msg_cl == b'q':  # 如果用户输入退出相关指令
                print('会话终止!!!')
                break
            data = cl.recv(1024)  # 接收服务器返回的信息
            print("服务器的消息:", data.decode())  # 打印服务器返回的消息

    elif choice == '2':
        path1 = input('请输入要上传的文件路径')  # 获取用户要上传的文件路径
        cl.send(b'2')
        with open(path1, 'rb') as f:  # 以二进制读取模式打开用户指定路径的文件
            for i in f:
                cl.send(i)  # 逐行发送文件内容到服务器
                data = cl.recv(1024)
                if data != b'success':  # 如果服务器返回的不是成功标识则中断上传
                    break
        cl.send(b'quit')
        print('文件上传结束!')

    elif choice == '3':
        path2 = input('请输入要下载的文件路径')
        cl.send(b'3')
        cl.send(path2.encode())  # 发送用户要下载的文件路径给服务器
        with open(path2, 'wb') as f:  # 以二进制写入模式打开文件准备接收内容
            while True:
                data = cl.recv(1024)
                if data == b'#end':  # 接收到结束标识则停止接收
                    break
                f.write(data)  # 将接收到的数据写入文件
        print('文件下载结束!')
    cl.close()  # 关闭套接字连接

server端代码

import socket
import os

ip_port = ('127.0.0.1', 8088)  # 客户端和服务器端的配置需保持一致

if __name__ == '__main__':
    sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建套接字,指定使用IPv4和TCP协议
    sk.bind(ip_port)  # 绑定服务器的IP地址和端口
    sk.listen(6)  # 开始监听,最多接受6个客户端连接
    print('等待接受信息')

    while True:
        conn, addr = sk.accept()  # 接受客户端的连接请求,conn用于与客户端通信,addr是客户端地址
        msg = '连接成功'
        conn.send(msg.encode())  # 向客户端发送连接成功的提示
        while True:
            data = conn.recv(1024)
            print("客户端的消息:", data.decode())  # 打印客户端发送的消息

            if data.decode() == '1':
                data = conn.recv(1024)
                print("客户端的消息:", data.decode())
                while True:
                    data = conn.recv(1024)
                    print("客户端的消息:", data.decode())
                    msg_server = input('要发送的信息:').encode()
                    conn.send(msg_server)
                    if data.decode() == 'quit' or data.decode() == 'q':
                        print('会话终止!!!')
                        break

            elif data.decode() == '2':
                print('文件接收开始')
                path1 = '请输入上传的文件路径'
                conn.send(path1.encode())  # 让客户端输入上传文件路径
                with open('file.txt', 'ab') as f:  # 以追加二进制写入模式打开文件接收内容
                    while True:
                        data = conn.recv(1024)
                        if data == b'quit' or data == b'q':
                            break
                        f.write(data)
                        conn.send('success'.encode())
                print('文件接收完成!!')

            elif data.decode() == '3':
                print('文件传输开始')
                path2 = '请输入要下载的文件路径'
                conn.send(path2.encode())
                file_name = conn.recv(1024).decode()
                if not os.path.exists(file_name):
                    conn.send(b'File not found')
                    break
                with open(file_name, 'rb') as f:  # 以二进制读取模式打开文件准备发送内容
                    while True:
                        data = f.read(1024)
                        if not data:
                            break
                        conn.send(data)
                conn.send(b'#end')

            elif data.decode() == 'quit' or data.decode() == 'q':
                print('会话终止!!!')
                break

        conn.close()  # 关闭与客户端的连接
© 版权声明

相关文章

没有相关内容!

暂无评论

none
暂无评论...