我試圖使用winsock實現一個簡單的FTP客戶端。我在嘗試下載文件時遇到問題。下面是我使用的時刻代碼:recv()只讀取1個字節(使用winsock實現FTP)
bool FTPHandler::downloadFile(const char * remoteFilePath, const char * filePath) {
if (!isConnected()) {
setErrorMsg("Not connected, imposible to upload file...");
return false;
}
if (usePasiveMode) {
this->pasivePort = makeConectionPasive();
if (this->pasivePort == -1) {
//error msg will be setted by makeConectionPasive()
return false;
}
} else {
setErrorMsg("Unable to upload file not in pasive mode :S");
return false;
}
char * fileName = new char[500];
getFileName(remoteFilePath,fileName);
// Default name and path := current directory and same name as remote.
if (filePath == NULL) {
filePath = fileName;
}
if (!setDirectory(remoteFilePath)) {
return false;
}
char msg[OTHER_BUF_SIZE];
char serverMsg[SERVER_BUF_SIZE];
sprintf(msg,"%s%s\n",RETR_MSG,fileName);
send(sock, msg, strlen(msg), 0);
SOCKET passSocket;
SOCKADDR_IN passServer;
passSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (passSocket == INVALID_SOCKET) {
WSACleanup();
sprintf(errorMsg,"Error trying to create socket (WSA error code: %d)",WSAGetLastError());
return false;
}
passServer.sin_family = PF_INET;
passServer.sin_port = htons(this->pasivePort);
passServer.sin_addr = *((struct in_addr *)gethostbyname(this->host)->h_addr);
memset(server.sin_zero,0,8);
int errorCode = connect(passSocket, (LPSOCKADDR) &passServer, sizeof(struct sockaddr));
int tries = 0;
while (errorCode == SOCKET_ERROR) {
tries++;
if (tries >= MAX_TRIES) {
closesocket(passSocket);
sprintf(errorMsg,"Error trying to create socket");
WSACleanup();
return false;
}
}
char * buffer = (char *) malloc(CHUNK_SIZE);
ofstream f(filePath);
Sleep(WAIT_TIME);
while (int readBytes = ***recv(passSocket, buffer, CHUNK_SIZE, 0)***>0) {
buffer[readBytes] = '\0';
f.write(buffer,readBytes);
}
f.close();
Sleep(WAIT_TIME);
recv(sock, serverMsg, OTHER_BUF_SIZE, 0);
if (!startWith(serverMsg, FILE_STATUS_OKEY_CODE)) {
sprintf(errorMsg,"Bad response: %s",serverMsg);
return false;
}
return true;
}
這最後的recv()返回1個字節幾次,然後該方法結束這應該是各地的1Kb的文件僅僅是23個字節。
爲什麼不recv讀洞文件?
什麼是23字節?另外,在打開與服務器的數據連接之前,我並不確定是否發佈了RETR。數據端口被打開後,服務器是否應該發送一些ACK消息,也就是說,客戶端應該在發佈RETR之前收聽ACK? – 2012-07-30 17:36:00
這23個字節看起來很像。如果我嘗試下載一個小文件(如50字節),那麼它只能讀取1個字節。我不認爲服務器應該發送任何ACK消息。 – 2012-07-30 18:08:01
好的,也許你是對的 - 自從我做這些東西以來,有一段時間了。接下來,'buffer [readBytes] ='\ 0'是什麼';'做?它似乎在數據的末尾放置了空值,然後不會寫入文件,所以它是多餘的。接下來,調試 - 到目前爲止你做了什麼?如果您在f.write中斷,readBytes的值和緩衝區中的值是什麼? – 2012-07-30 19:18:01