继上一篇博文实现Linux下的shell后,我们进一步利用网络编程和系统编程的知识实现Linux下的FTP服务器。我们以vsftpd为原型并实现了其大部分的功能。由于篇幅和时间的关系,这里不再一一赘述具体的实现过程,而是简要概述功能实现思想和部分核心代码。
(一)基本框架和流程
先解决两个疑问:
(1)为什么要使用nobody进程和服务进程两个进程?
在PORT模式下,服务器会主动建立数据通道连接客户端,服务器可能就没有权限做这种事情,就需要nobody进程来帮忙。 Nobody进程会通过unix域协议(本机通信效率高) 将套接字传递给服务进程。普通用户没有权限绑定20端口,需要nobody进程的协助,所以需要nobody进程作为控制进程。
(2)为什么使用多进程而不是多线程?
原因是在多线程或IO复用的情况下,当前目录是共享的,无法根据每一个连接来拥有自己的当前目录,也就是说当前用户目录的切换会影响到其他的用户。
(二)主被动模式的实现
主被动是相对于服务器来说的:
主动模式:服务器向客户端敲门,然后客户端开门
被动模式:客户端向服务器敲门,然后服务器开门
被动模式的出现主要是为了解决 防火墙或者NAT造成的问题。当通过NAT转换之后,服务器只能得知NAT的地址而不能得知客户端的IP地址,因此服务器以20端口主动向NAT的PORT端口发动请求,但是NAT并没有启用PORT端口,所以连接会被拒绝。
int get_transfer_fd(session_t *sess)
{
// 检测是否收到PORT或者PASV命令