使用 Socket 通信实现 FTP 客户端程序(二)

转载自:http://www.ibm.com/developerworks/cn/linux/l-cn-socketftp/index.html#FTP

这是我自己写的客户端程序:http://download.csdn.net/detail/sphone89/4060069

Socket 编程的几个重要步骤

Socket 客户端编程主要步骤如下:

    1、socket() 创建一个 Socket

    2、connect() 与服务器连接

    3、write() 和 read() 进行会话

    4、close() 关闭 Socket

Socket 服务器端编程主要步骤如下:

  1. socket() 创建一个 Socket
  2. bind()
  3. listen() 监听
  4. accept() 接收连接的请求
  5. write() 和 read() 进行会话
  6. close() 关闭 Socket

实现 FTP 客户端上传下载功能

         1、客户端和 FTP 服务器建立 Socket 连接。

         2、向服务器发送 USER、PASS 命令登录 FTP 服务器。

        3、使用 PASV 命令得到服务器监听的端口号,建立数据连接。

         4、使用 RETR/STOR 命令下载/上传文件。

        5、在下载完毕后断开数据连接并发送 QUIT 命令退出。

 

客户端和 FTP 服务器建立 Socket 连接

当客户端与服务器建立连接后,服务器会返回 220 的响应码和一些欢迎信息。


图 1. 客户端连接到服务器端

清单 1. 客户端连接到 FTP 服务器,接收欢迎信息
SOCKET control_sock;

struct hostent *hp;

struct sockaddr_in server;

memset(&server, 0, sizeof(struct sockaddr_in));/* 初始化socket */

control_sock = socket(AF_INET, SOCK_STREAM, 0);

hp = gethostbyname(server_name);

memcpy(&server.sin_addr,

hp->h_addr, hp->h_length);

server.sin_family = AF_INET;

server.sin_port = htons(port);

/* 连接到服务器端 */

connect(control_sock,(struct sockaddr *)&server, sizeof(server));

/* 客户端接收服务器端的一些欢迎信息 */

read(control_sock, read_buf, read_len);

 

客户端登录 FTP 服务器

当客户端发送用户名和密码,服务器验证通过后,会返回 230 的响应码。然后客户端就可以向服务器端发送命令了。
图 2. 客户端登录 FTP 服务器

清单 2. 客户端发送用户名和密码,登入 FTP 服务器
/* 命令 ”USER username\r\n” */

sprintf(send_buf,"USER %s\r\n",username);/*客户端发送用户名到服务器端 */

write(control_sock, send_buf, strlen(send_buf))

;/* 客户端接收服务器的响应码和信息,正常为 ”331 User name okay, need password.” */

read(control_sock, read_buf, read_len);

/* 命令 ”PASS password\r\n” */

sprintf(send_buf,"PASS %s\r\n",password);

/* 客户端发送密码到服务器端 */

write(control_sock, send_buf, strlen(send_buf));

/* 客户端接收服务器的响应码和信息,正常为 ”230 User logged in, proceed.” */

read(control_sock, read_buf, read_len);

 

客户端让 FTP 服务器进入被动模式

当客户端在下载/上传文件前,要先发送命令让服务器进入被动模式。服务器会打开数据端口并监听。并返回响应码 227 和数据连接的端口号。

图 3. 客户端让服务器进入被动模式


清单 3. 让服务器进入被动模式,在数据端口监听
/* 命令 ”PASV\r\n” */

sprintf(send_buf,"PASV\r\n");

/* 客户端告诉服务器用被动模式 */

write(control_sock, send_buf, strlen(send_buf));

/*客户端接收服务器的响应码和新开的端口号,* 正常为 ”227 Entering passive mode (<h1,h2,h3,h4,p1,p2>)” */

read(control_sock, read_buf, read_len);

 

客户端通过被动模式下载文件

当客户端发送命令下载文件。服务器会返回响应码 150,并向数据连接发送文件内容。


图 4. 客户端从FTP服务器端下载文件

客户端退出服务器

当客户端下载完毕后,发送命令退出服务器,并关闭连接。服务器会返回响应码 200。


图 5. 客户端从 FTP 服务器退出

首先,服务器准备就绪后返回 220。客户端接收到服务器端返回的响应码后,相继发送“USER username” 和 “PASS password” 命令登录。随后,服务器返回的响应码为 230 开头,说明客户端已经登入了。这时,客户端发送 PASV 命令让服务器进入被动模式。服务器返回如 “227 Entering Passive Mode (127,0,0,1,13,67)”,客户端从中得到端口号,然后连接到服务器的数据端口。接下来,客户端发送下载命令,服务器会返回响应码 150,并从数据端口发送数据。最后,服务器返回 “226 transfer complete”,表明数据传输完成。

需要注意的是,客户端不要一次发送多条命令,例如我们要打开一个目录并且显示这个目录,我们得发送 CWD dirname,PASV,LIST。在发送完 CWD dirname 之后等待响应代码,然后再发送后面一条。当 PASV 返回之后,我们打开另一个 Socket 连接到相关端口上。然后发送 LIST,返回 125 之后在开始接收数据,最后返回 226 表明完成。

在传输多个文件的过程中,需要注意的是每次新的传输都必须重新使用 PASV 获取新的端口号,接收完数据后应该关闭该数据连接,这样服务器才会返回一个 2XX 成功的响应。然后客户端可以继续下一个文件的传输。

上传文件与下载文件相比,登入验证和切换被动模式都如出一辙,只需要改变发送到服务器端的命令,并通过数据连接发送文件内容。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值