2016-10-10 112 views
0

我想在C++中使用BSD套接字創建FTP客戶端,我可以創建套接字,獲取歡迎消息,發送用戶名,但我無法繼續前進。這裏是我的dubug輸出:在FTP客戶端recv()

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分鐘stucked,服務器終止連接,我終於得到迴應:

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 protected]\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

當服務器詢問時,您是否嘗試過發送電子郵件地址?我猜其餘的都是跟進錯誤。你應該避免這樣的:'421登錄超時(300秒):關閉控制連接' – Hayt

+0

@Hayt是的,我試過。我的程序如下所示: 'const char * usernameMsg =「USER anonymous \ r \ n」;' 'communication(sock,usernameMsg);' 'const char * passwdMsg =「PASS [email protected] \ r \ (sock,「pass」);' ''通信襪子,「LIST \ r \ n」);' '通訊(襪子,「QUIT \ r \ n」);' –

+0

@TomášHrnčiar請更新您的問題。作爲評論幾乎不可讀。 –

回答

1

你顯然希望recv返回0,當沒有更多的服務器響應。

但這是阻塞模式的錯誤。在阻止模式下,recv將一直等到有一些數據。請注意,套接字是連接的通用接口。連接只是一個數據流。沒有結束的訊息標記。所以套接字不能奇蹟般地發現從FTP服務器收到完整的響應。隨你便。您只需撥打recv,直到您收到CRLF序列,該序列表示FTP協議中的結束響應。而且它實際上更復雜,因爲FTP響應可以是多線的。閱讀FTP規範。


你現在的主要問題是,你的第一個電話communication()函數永遠不會結束。

一旦閱讀331響應於USER命令,開始等待下一個信息(第二輪[甚至更晚,在罕見的情況下,331響應大於2000個字符]在所述while環的第一次調用communication()函數)。但服務器實際上正在等待你的下一個命令,你永遠不會發送。所以服務器最終放棄了,向你發送421響應並斷開你的連接。