计算机网络原理

课程设计是实现FTP客户端和服务端。

FTP

实验内容

我实现了FTP的客户端和服务端,除了PUT、GET、?等还实现了SITE、MKD、RMD、RNFR、SIZE等大量命令,以及active/passive模式的切换、ascii/image类型的RETR等。

客户端

源代码为src/client/目录及src/*.ccsrc/*文件为客户端与服务端共用。

命令行选项帮助

% build/ftp -h
FTP client.

Usage: build/ftp [options] [uri]
Options:
  -d, --debug
  -h, --help      display this help and exit
  -q, --quiet

Report bugs to i@maskray.me

命令行提示符

使用了ANSI escape code产生颜色。

命令行补全

使用了readline库进行命令补全,相关代码在src/client/completion.cc里。如下终端会话为键入了命令的开头字母后按TAB补全得到的。

% build/ftp 127.1
ftp >>= l
list   login  ls
ftp >>= m
md     mkdir

cat命令

以ASCII data type显示服务端文件。

ftp /upload >>= cat ii
ddfsdafffffffffffffffffffffffffffffffffffffff

命令行选项:-d 调试

-d选项会输出客户端与服务端的所有通信内容。

% build/ftp -d 127.1
--> 220 ProFTPD 1.3.4d Server (ProFTPD Default Server) [::ffff:127.0.0.1]
ftp >>= login
Login (anonymous):
--> USER anonymous
--> 331 Anonymous login ok, send your complete email address as your password
Password:
--> PASS
--> 230 Anonymous access granted, restrictions apply
--> PWD
--> 257 "/" is the current directory
ftp / >>= get ii -o ggg
--> PASV
--> 227 Entering Passive Mode (127,0,0,1,141,120).
--> TYPE I
--> 200 Type set to I
--> RETR ii
--> 550 ii: No such file or directory
ftp /upload >>= cd upload
--> CWD upload
--> 250 CWD command successful
--> PWD
--> 257 "/upload" is the current directory
ftp /upload >>= get ii -o ggg
--> PASV
--> 227 Entering Passive Mode (127,0,0,1,163,63).
--> TYPE I
--> 200 Type set to I
--> RETR ii
--> 150 Opening BINARY mode data connection for ii (46 bytes)
ftp /upload >>=

Active模式

默认使用passive模式(FTP协议默认使用active模式),active命令可以切换到active模式。

ftp / >>= active
ftp / >>= ls
--> PORT 127,0,0,1,209,75
--> 200 PORT command successful
--> LIST
--> 150 Opening ASCII mode data connection for file list
-rw-r--r--   1 ftp      ftp          1907 Sep 28 05:44 10.cc
drwxr-xr-x   2 ftp      ftp          4096 Dec 26 13:53 a
--> 226 Transfer complete
ftp / >>=

IPv6支持

当服务端地址为IPv6时,会选择使用EPSVEPRT 代替PASVPORT

% build/ftp -d ::1
<-- 220 ProFTPD 1.3.4d Server (ProFTPD Default Server) [::1]
ftp >>= login
Login (anonymous):
--> USER anonymous
<-- 331 Anonymous login ok, send your complete email address as your password
Password:
--> PASS
<-- 230 Anonymous access granted, restrictions apply
--> PWD
<-- 257 "/" is the current directory
ftp / >>= ls
--> EPSV
<-- 229 Entering Extended Passive Mode (|||1226|)
--> LIST
<-- 150 Opening ASCII mode data connection for file list
drwxr-xr-x   2 ftp      ftp          4096 Feb  1  2013 distfiles
drwxrwxrwx   9 ftp      ftp          4096 Dec 26 13:54 upload
<-- 226 Transfer complete
ftp / >>= active
ftp / >>= ls
--> EPRT |2|::1|40632|
<-- 200 EPRT command successful
--> LIST
<-- 150 Opening ASCII mode data connection for file list
drwxr-xr-x   2 ftp      ftp          4096 Feb  1  2013 distfiles
drwxrwxrwx   9 ftp      ftp          4096 Dec 26 13:54 upload
<-- 226 Transfer complete
ftp / >>=

帮助

ftp >>= ?
All commands: active, cat, cd, cdup, chdir, chmod, connect, close, debug, dir, get, help, lcd, login, list, lpwd, ls, md, mkdir, mv, open, passive, put, pwd, quit, quote, rhelp, rd, rmdir, site, size, ?
ftp >>= ? get
Usage: get [options] rfile
Options:
  -a, --ascii     use ascii mode (default: binary)
  -o, --output    local file name (default: basename of rfile)
  -h, --help      help

服务端

源代码为src/server/目录及src/*.ccsrc/*文件为客户端与服务端共用。

IPv6支持

使用-6命令行选项监听IPv6地址而非IPv4地址。

daemon模式

默认使用daemon(3)脱离控制终端并把stdin、stdout、stderr重定向至/dev/null。可以加上选项-n防止变为daemon。

% sudo build/ftpd -6nd /tmp
--> 220 Ready
<-- USER anonymous
--> 331 Anonymous login ok, send your complete email address as your password
<-- PASS
--> 230 Anonymous access granted
<-- PWD
--> 257 "/tmp" is the current directory

监听端口

选项-p用于指定监听端口。

% build/ftpd /tmp -p 2121

passive模式端口选择

指定sockaddr_insin_port字段为0,这样bind会随机选择一个端口。这是4.2BSD socket API的行为,大多数socket实现也都具有这一未被写在文档上的特性。