計算機網絡原理

課程設計是實現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實現也都具有這一未被寫在文檔上的特性。