我正在尝试使用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");
你可以告诉我,有什么问题吗?谢谢
答案 0 :(得分:1)
您显然希望recv
返回0,此时服务器不再响应。
但这对于阻止模式来说是错误的。在阻止模式下,recv
将一直等到有一些数据。请注意,套接字是连接的通用接口。连接只是一个数据流。没有消息结束标记。因此套接字无法神奇地发现从FTP服务器收到了完整的响应。它取决于你。您只能在收到CRLF序列之前调用recv
,该序列表示FTP协议中的响应结束。它实际上更复杂,因为FTP响应可以是多线的。阅读FTP规范。
您现在的首要问题是,您对communication()
功能的第一次调用永远不会完成。
在您阅读331
命令的USER
响应后,您开始等待下一条消息(第二轮[甚至更晚,在极少数情况下331
响应更长在while
函数的第一次调用中communication()
循环的2000个字符]。但是服务器实际上正在等待你从未发送过的下一个命令。因此服务器最终放弃,向您发送421
响应并断开连接。