简介
感觉没有特别顺手的临时文件传输程序。写个demo试试。
代码可以做客户端也可以做服务端。
做为服务器端时,客户端可以发送文件给服务端,也可以从服务端获取文件。
环境
- 系统:win10(兼容Linux)
- Python:Python 3.8.1(兼容Python 2.7)
使用说明
作为服务端
命令格式:python demo.py server {server_ip} {server_port}
- server:server模式
- server_ip:服务端地址
- server_port:服务端端口(自己随便设置)
例:python demo.py server 127.0.0.1 8000
作为客户端
命令格式:python demo.py client {server_ip} {server_port} { sendfile source_fullpath taget_filename| recvfile taget_filename storage_fullpath | exit }
- client:client模式
- server_ip:服务端地址(与server对应)
- server_port:服务端端口(与server对应)
- sendfile source_fullpath taget_filename:从客户端向服务端发送文件,客户端文件全路径,将保存在服务端上的文件名
例:python demo.py client 127.0.0.1 8000 sendfile D:/123.txt 456.txt
(发送客户端D:/123.txt到服务端demo.py同目录下456.txt) - recvfile taget_filename storage_fullpath:从服务端获取文件,服务端文件名,将保存在客户端上的文件全路径
例:python demo.py client 127.0.0.1 8000 recvfile 456.txt D:/123.txt
(接收服务端demo.py同目录下456.txt到客户端D:/123.txt) - exit:退出服务端
demo代码
demo.py
# coding: utf-8
# 20200627 by
import socket
import sys
import os
def get_script_path():
return os.path.split(os.path.realpath(__file__))[0]
# 正向接收文字
def s_00(conn):
data_len = int(conn.recv(10).decode('utf-8'))
data = b''
cache_size = 35
if data_len % cache_size == 0:
cache_size += 1
for i in range(int(data_len / cache_size) + 1):
data += conn.recv(cache_size)
print(data.decode('utf-8') + '\n')
return True
# 正向接收文件
def s_01(conn):
filename_len = int(conn.recv(10).decode('utf-8'))
filename = conn.recv(filename_len).decode('utf-8')
print('[+] Recv file: {filename}'.format(filename=filename))
f = open('{path}/{filename}'.format(path=get_script_path(), filename=filename),'wb')
while True:
data = conn.recv(1024)
if not data:
break
f.write(data)
f.close()
# 反向发送文字
def s_10(conn):
pass
# 反向发送文件
def s_11(conn):
filename_len = int(conn.recv(10).decode('utf-8'))
filename = conn.recv(filename_len).decode('utf-8')
print('[+] Send file: {filename}'.format(filename=filename))
f = open('{path}/{filename}'.format(path=get_script_path(), filename=filename), 'rb')
while True:
data = f.read(1024)
if not data:
break
conn.send(data)
f.close()
def server(host, port):
server_handle = {
'00': s_00,
'01': s_01,
'10': s_10,
'11': s_11,
}
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((str(host), int(port)))
s.listen(1)
while True:
# 等待连接后分配会话,获取地址addr[0]
conn, addr = s.accept()
print('[+] Accept source address: {addr}'.format(addr=addr[0]))
# 等待数据
handle = conn.recv(2).decode('utf-8')
# 格式:^(?P<模式>d)(?P<数据类型>d)(?P<数据长度>d{10})(?P<数据>d)
# 1. 模式:
# 0. 正向模式
# 1. 反向模式
# 2. 数据类型:
# 0. 文字
# 1. 文件
# 3. 数据长度:
# 文字长度/文件名长度
# 4. 数据:
# 二进制数据
if handle == '':
conn.close()
continue
fun = server_handle.get(handle, None)
if fun == None and handle != '':
break
fun(conn)
conn.close()
s.close()
# 发送文字
def c_00(s):
data = sys.argv[5]
data_len = str(len(data.encode('utf-8'))).zfill(10)
string = '00' + data_len + data
s.send(string.encode('utf-8'))
# 发送文件
# source_fullpath 456.txt
def c_01(s):
mode = '01'.encode('utf-8')
source_fullpath = sys.argv[5]
filename = sys.argv[6].encode('utf-8')
filename_len = str(len(filename)).zfill(10).encode('utf-8')
s.send(mode + filename_len + filename)
f = open(source_fullpath, 'rb')
while True:
data = f.read(1024)
if not data:
break
s.send(data)
f.close()
# 获取文字
def c_10(s):
pass
# 获取文件
# taget_filename.txt D:/456.txt
def c_11(s):
mode = '11'.encode('utf-8')
taget_filename = sys.argv[5].encode('utf-8')
taget_filename_len = str(len(taget_filename)).zfill(10).encode('utf-8')
storage_fullpath = sys.argv[6]
f = open(storage_fullpath, 'wb')
s.send(mode + taget_filename_len + taget_filename)
while True:
data = s.recv(1024)
if not data:
break
f.write(data)
f.close()
def c_12(s):
mode = '12'.encode('utf-8')
s.send(mode)
def client(host, port):
client_handle = {
'sendinfo': c_00,
'sendfile': c_01,
'recvinfo': c_10,
'recvfile': c_11,
'exit': c_12
}
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((str(host), int(port)))
fun = client_handle.get(sys.argv[4], None)
if fun == None:
print('[-] Unknown command: {command}'.format(command=sys.argv[4]))
else:
fun(s)
s.close()
if __name__ == "__main__":
mode = {
'server': server,
'client': client
}
host = sys.argv[2]
port = sys.argv[3]
fun = mode.get(sys.argv[1], None)
if fun != None:
fun(host, port)