FTP客户端中的recv()

时间:2016-10-10 13:58:56

标签: c++ sockets ftp

我正在尝试使用BSD套接字在C ++中创建FTP客户端,我可以创建套接字,获取欢迎消息,发送用户名,但我无法继续前进。这是我的dubug输出:

Socket created
Connected

220 server - welcome message

Msg: USER anonymous

Received bytes: 75
331 Anonymous login ok, send your complete email address as your password

然后我被困在这一点上5分钟,服务器终止连接,我终于得到了回复:

Received bytes: 61
331 Anonymous login ok, send your complete email address as your password
421 Login timeout (300 seconds): closing control connection
our password

Received bytes: 0
Msg: PASS password

Received bytes: 0
Msg: SYST

Received bytes: 0
Msg: PASV

Received bytes: 0
Msg: LIST

Received bytes: 0
Msg: QUIT

Received bytes: 0
Program ended with exit code: 0

这是我发送和接收消息的功能。我为FTP服务器添加了套接字和消息(例如USER anonymous\r\n

void communication(int sock, const char *msg) {
string response;
char server_reply[2000];
printf("Msg: %s\n", msg);
send(sock, msg, strlen(msg), 0);
//Receive a reply from the server
int rval;
do
{
    rval = (int) recv(sock , server_reply , 2000 , 0);
    printf("Received bytes: %d\n", rval);
    if (rval <= 0)
    {
        break;
    }
    else {
        response.append(server_reply);
        puts(response.c_str());
    }
}
while (true);

我的程序如下:

//Receive a welcome message from the server
if( recv(sock , server_reply , 2000 , 0) < 0) {
    puts("recv failed");
}

puts(server_reply);
memset(&server_reply[0], 0, sizeof(server_reply));

const char *usernameMsg = "USER anonymous\r\n";`
communication(sock, usernameMsg);`
const char *passwdMsg = "PASS email@email.com\r\n";`
communication(sock, passwdMsg);
communication(sock, "SYST\r\n");
communication(sock, "PASV\r\n");
communication(sock, "LIST\r\n");
communication(sock, "QUIT\r\n");
你可以告诉我,有什么问题吗?谢谢

1 个答案:

答案 0 :(得分:1)

您显然希望recv返回0,此时服务器不再响应。

但这对于阻止模式来说是错误的。在阻止模式下,recv将一直等到有一些数据。请注意,套接字是连接的通用接口。连接只是一个数据流。没有消息结束标记。因此套接字无法神奇地发现从FTP服务器收到了完整的响应。它取决于你。您只能在收到CRLF序列之前调用recv,该序列表示FTP协议中的响应结束。它实际上更复杂,因为FTP响应可以是多线的。阅读FTP规范。

您现在的首要问题是,您对communication()功能的第一次调用永远不会完成。

在您阅读331命令的USER响应后,您开始等待下一条消息(第二轮[甚至更晚,在极少数情况下331响应更长在while函数的第一次调用中communication()循环的2000个字符]。但是服务器实际上正在等待你从未发送过的下一个命令。因此服务器最终放弃,向您发送421响应并断开连接。