基于Socket实现信息交互和文件上传及下载

实验介绍:

用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() #实例化函数,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:    #重复执行下面的代码,直到break
        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:  #with open打开用户指定路径的文件,rb(二进制读取)模式
        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) # socket.AF_INET 指 传输协议是ipv4,socket.SOCK_STREAM表示使用tcp协议。创建套接字sk,用套接字来连接。
sk.bind(ip_port) #sk.bind代表sk使用bind函数绑定IP和端口。
sk.listen(6) #接受6个客户端
print(‘等待接受信息’)

while True:
    conn,addr = sk.accept()       #接受客户端的连接请求。addr代表客户端的地址,创建套接字conn用于和客户端通信
    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()