文件传输协议(FTP)
FTP主要用于匿名下载公共文件,也可以用于在两台计算机之间传输文件,特别是在使用WIndows进行工作而文件存储系统使用UNIX的情况下。早在Web流行之前,FTP就是在因特网上进行文件传输以及下载软件和源代码的主要手段之一
FTP要求输入用户名和密码才能访问远程FTP服务器,但也允许没有帐号的用户匿名登录,不过需要管理员设置FTP服务器以允许匿名用户登录
FTP协议工作流程:
1.客户端连接远程主机上的FTP服务器
2.客户端输入用户名和密码
3.客户端进行各种文件传输和信息查询操作
4.客户端从远程FTP服务器退出,结束传输
因特网上的FTP客户端和服务器。客户端与服务器在命令与控制端窗口通过FTP协议通信,而数据通过数据端口传输
当然这只是一般的工作流程,当网络问题或计算机崩溃时,会导致整个传输在完成之前就中断,如果客户端超过15分钟(900秒)还没有响应,FTP就会超时并且中断
在底层FTP使用的TCP,可以将FTP看作客户端/服务器便曾中的特殊情况,因为这里的客户端和服务器都是用两个套接字来通信:一个是控制和命令端口(21号端口),另一个是数据端口(有时是20号端口)
用python进行简单模拟FTP文件上传
思路就是客户端选择文件进行读取并发送给服务器端,服务器获取数据然后在进行写入操作,最后进行文件大小的确认
(这里的socket只是简单的考虑1对1,即客户端发送只发送一个文件,服务器端也只接收一个文件)
服务端
import errno
import selectors
import socket
import os, time
def accept(sock, mask):
conn, addr = sock.accept()
conn.setblocking(False)
sel.register(conn, selectors.EVENT_READ, read)
def read(conn, mask):
file_name = conn.recv(1024).decode()
if os.path.isfile(file_name):
file_size = os.stat(file_name).st_size
conn.send(str(file_size).encode('utf-8'))
print(file_size)
# print(conn.recv(1024))
with open(file_name, 'rb') as f:
for line in f:
if line != '':
print(line)
conn.send(line)
print('over')
else:
conn.send(b'0')
if __name__ == '__main__':
sel = selectors.DefaultSelector()
sock = socket.socket()
sock.bind(('localhost', 9999))
sock.listen()
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)
while True:
events = sel.select()
for key, mask in events:
callaback = key.data
callaback(key.fileobj, mask)
客户端
import socket
client = socket.socket()
client.connect(('localhost', 9999))
while True:
cmd = input('file name <<:')
if len(cmd) == 0:
continue
client.send(cmd.encode('utf-8'))
server_size = client.recv(1024).decode()
file_size = 0
if server_size != '0':
f = open('2'+cmd , 'wb')
while file_size < int(server_size) :
print(file_size, server_size)
data = client.recv(1024)
if data:
file_size += len(data)
f.write(data)
else:
print('err')
continue
# print(data)
f.close()
print('file over')