0x01 基础知识

1、bytes和string类型的相互转换:

s = "hello world"  # 定义字符串变量
bytes = s.encode('utf-8')  #转换为bytes类型
str = bytes.decode()  #转换为string类型

2、获取命令行的传参

import sys
import getopt #导入getopt模块

opts, args = getopt.getopt(sys.argv[1:],"a:b:c") #opts接收命令行传入的参数和值
print(opts) #输出所有参数及值

for o,a in opts:  # o存储了短选项,a存储了短选项的值
    print(o[1:],":",a)

0x02 编程思路

1、定义help函数,打印输出信息
2、利用getopt获取命令行参数
3、区分客户端和服务器
4、编写客户端函数和服务端函数
5、编写文件上传函数、文件下载函数

0x03 编程步骤

1、定义help函数,打印输出信息

def help():
    print("help info:")
    print("server:python3 uploads.py -lp [port]")
    print("client:python3 uploads.py -t [target] -p [port] -u [filename]")
    sys.exit()

2、利用getopt获取命令行参数

opts, args = getopt.getopt(sys.argv[1:],"t:p:u:lh")
for o,a in opts:  #for循环读取传参并赋值给对应的变量
        if o == "-h":
            need_help = True
        elif o == "-l":
            listen = True
        elif o == "-t":
            target = a
        elif o == "-p":
            port = int(a)
        elif o == "-u":
            filename = a
        else:
            #传参错误
            assert False , "[x] Unhandled Option!"

3、区分客户端和服务器

if listen:
        print("server:port %d is listening" % port)
        server(target,port) #服务端
    else:
        print("client:target is :%s,port is %s,filename is %s" % (target,port,filename))
        client(target,port) #客户端

4、编写客户端函数和服务端函数

#客户端
def client(target,port):
    cli = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #建立socket连接对象
    cli.connect((target,port))  #发起socket连接
    cli.send(filename.encode("utf-8"))  #发送文件名
    print("[*] File name sent successfully.")
    time.sleep(1)  #沉睡1秒,防止同时发送文件名和文件内容报错
    upload_file(cli)  #调用文件上传函数,传入socket对象
    cli.close()

#服务端
def server(target,port):
    ser = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    ser.bind((target,port))  #绑定IP和端口
    ser.listen(10)  #开启监听
    print("[*]Listening on %s:%d." %(target,port))
    while True:
        cli_socket,addr = ser.accept()  #接收socket连接传递的内容
        download_file(cli_socket)  #调用文件下载函数,传入cli_socket对象
        break

5、编写文件上传函数、文件下载函数

#文件上传
def upload_file(cli):
    f = open(filename,"rb")
    data = f.read()  #将文件内容存储到data变量
    f.close()
    cli.send(data)  #通过socket连接发送文件内容
    print("[*] File sent successfully.")

#文件下载
def download_file(cli_socket):
    filename = cli_socket.recv(4096)  #接收文件名
    filename = filename.decode()
    temp = "".encode("utf-8")  #创建临时变量,用于接收文件内容
    while True:
        data = cli_socket.recv(4096)
        if not data:
            break
        else:
            temp += data
    f = open(filename,"wb")
    f.write(temp)  #将文件内容写入本地文件
    f.close()
    print("[*] File %s sent successfully." % filename)

0x04 实现效果

文件上传.gif

0x05 完整代码

#1、定义help函数,打印输出信息
#2、利用getopt获取命令行参数
#3、区分客户端和服务器
#4、编写客户端函数和服务端函数
#5、编写文件上传函数、文件下载函数

import sys
import socket  #导入socket库,创建socket连接
import getopt  #获取传参
import time
filename = ""  #定义文件名全局变量

#1、定义help函数,打印输出信息
def help():
    print("help info:")
    print("server:python3 uploads.py -lp [port]")
    print("client:python3 uploads.py -t [target] -p [port] -u [filename]")
    sys.exit()

def main():
    global filename
    # 2、利用getopt获取命令行参数
    opts, args = getopt.getopt(sys.argv[1:],"t:p:u:lh")
    need_help = False
    listen = False  #定义listen变量是否监听,区分客户端和服务端
    target = ""
    port = 0
    for o,a in opts:  #for循环读取传参并赋值给对应的变量
        if o == "-h":
            need_help = True
        elif o == "-l":
            listen = True
        elif o == "-t":
            target = a
        elif o == "-p":
            port = int(a)
        elif o == "-u":
            filename = a
        else:
            #传参错误
            assert False , "[x] Unhandled Option!"

    if need_help:
        help()

    # 3、区分客户端和服务器
    if listen:
        print("server:port %d is listening" % port)
        server(target,port) #服务端
    else:
        print("client:target is :%s,port is %s,filename is %s" % (target,port,filename))
        client(target,port) #客户端

#4、编写客户端函数和服务端函数
#客户端
def client(target,port):
    cli = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #建立socket连接对象
    cli.connect((target,port))  #发起socket连接
    cli.send(filename.encode("utf-8"))  #发送文件名
    print("[*] File name sent successfully.")
    time.sleep(1)  #沉睡1秒,防止同时发送文件名和文件内容报错
    upload_file(cli)  #调用文件上传函数,传入socket对象
    cli.close()

#服务端
def server(target,port):
    ser = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    ser.bind((target,port))  #绑定IP和端口
    ser.listen(10)  #开启监听
    print("[*]Listening on %s:%d." %(target,port))
    while True:
        cli_socket,addr = ser.accept()  #接收socket连接传递的内容
        download_file(cli_socket)  #调用文件下载函数,传入cli_socket对象
        break

#5、编写文件上传函数、文件下载函数
#文件上传
def upload_file(cli):
    f = open(filename,"rb")
    data = f.read()  #将文件内容存储到data变量
    f.close()
    cli.send(data)  #通过socket连接发送文件内容
    print("[*] File sent successfully.")

#文件下载
def download_file(cli_socket):
    filename = cli_socket.recv(4096)  #接收文件名
    filename = filename.decode()
    temp = "".encode("utf-8")  #创建临时变量,用于接收文件内容
    while True:
        data = cli_socket.recv(4096)
        if not data:
            break
        else:
            temp += data
    f = open(filename,"wb")
    f.write(temp)  #将文件内容写入本地文件
    f.close()
    print("[*] File %s sent successfully." % filename)

if __name__ == "__main__":
    main()