⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpcli.cpp

📁 dget是一个基于Linux平台的多线程下载工具, 采用C++开发。主要支持FTP, HTTP, MMS, RTSP协议下载, 目前为止主要实现了FTP, HTTP, MMS,RTSP协议的多线程下载
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 	int Tos = IPTOS_THROUGHPUT;			FILE * fp = NULL;	float Per;	int DataSock = DataSkp->GetSockfd();	Length = This->RemoteEndPos - This->RemoteStartPos; 	    if (!(fp = fopen(This->LocalFile, This->FileMode)))    {		Disconnect();		close(DataSock);		This->Status = LOCALFATAL;		return FOPENERR;    }    setsockopt(DataSock, IPPROTO_IP, IP_TOS, (char *)&Tos, sizeof(Tos));	setvbuf(fp, NULL, _IONBF, 0);		This->Status = DOWNLOADING;	    while(Length > 0)    {		if(Length < FTP_BUF_SIZE && Length > 0)		{	    	while(Length > 0)	    	{	    						BytesRead = ReadMsg(DataSock, szBuffer, Length);								if (BytesRead == -1)				{		    		ShowMsg("error receving data");		    		fclose(fp);										Disconnect();		    		close(DataSock);						    		if(errno == ETIMEDOUT)		    		{						ShowMsg("TThread timed out");						This->Status = TIMEDOUT;						return READERR;		    		}						    		This->Status = REMOTEFATAL;		    		return READERR;				}				if (BytesRead != fwrite(szBuffer, sizeof(char), BytesRead, fp))				{		    		ShowMsg("write failed");		    		fclose(fp);					Disconnect();		    		close(DataSock);		    		This->Status = LOCALFATAL;		    		return FWRITEERR;				}							Length -= BytesRead;				Total += BytesRead;				This->RemoteBytesReceived += BytesRead;#ifdef DEBUG			Per = This->RemoteBytesReceived * 100 / This->BlkSize;			ShowMsg("%s has finished %.1f%%", This->Name, Per);#endif#ifdef USE_QT//			This->Task->DoInterface();#endif			}	    	break;		}		BytesRead = ReadMsg(DataSock, szBuffer, FTP_BUF_SIZE);		if(BytesRead == -1)		{	    	ShowMsg("error receving data");	    	fclose(fp);			Disconnect();	    	close(DataSock);	    	if (errno == ETIMEDOUT)	    	{				ShowMsg("TThread timed out");				This->Status = TIMEDOUT;				return READERR;	    	}	    	This->Status = REMOTEFATAL;	    	return READERR;		}		if(BytesRead != fwrite(szBuffer, sizeof(char), BytesRead, fp))		{	    	ShowMsg("write failed");	    	fclose(fp);			Disconnect();	    	close(DataSock);	    	This->Status = LOCALFATAL;	    	return FWRITEERR;		}				Length -= BytesRead;		Total += BytesRead;		This->RemoteBytesReceived += BytesRead;#ifdef DEBUG			Per = This->RemoteBytesReceived * 100 / This->BlkSize;		ShowMsg("%s has finished %.1f%%", This->Name, Per);#endif#ifdef USE_QT			//		This->Task->DoInterface();#endif    }    fclose(fp);	    This->Status = ALLDONE;	    Disconnect();    close(DataSock);    ShowMsg("download for this thread completed");    ShowMsg("%s : %ld received", This->LocalFile, Total);    return FTPOK;}uerr_t TFtpCli ::RetrFileUnknownSize(TThread * This){	long BytesRead;		FILE * fp = NULL;	char szBuffer[FTP_BUF_SIZE];	int Tos = IPTOS_THROUGHPUT;	int DataSock = DataSkp->GetSockfd();	    if (!(fp = fopen(This->LocalFile, This->FileMode)))    {		Disconnect();		close(DataSock);		This->Status = LOCALFATAL;		return FOPENERR;    }    setsockopt(DataSock, IPPROTO_IP, IP_TOS, (char *)&Tos, sizeof(Tos));    setvbuf(fp, NULL, _IONBF, 0);    	This->Status = DOWNLOADING;    do    {		BytesRead = Recv(DataSock, szBuffer, FTP_BUF_SIZE, 0);		if (BytesRead > 0)		{	    	if (fwrite(szBuffer, sizeof(char), BytesRead, fp) < BytesRead)	    	{				fclose(fp);				Disconnect();				close(DataSock);				ShowMsg("write failed");				This->Status = LOCALFATAL;				return FWRITEERR;	    	}	   		This->RemoteBytesReceived += BytesRead;		}    }while (BytesRead > 0);    fclose(fp);	    if (BytesRead == -1)    {		if (errno == ETIMEDOUT)		{	    	ShowMsg("TThread timed out");	    	This->Status = TIMEDOUT;	    	return READERR;		}		This->Status = REMOTEFATAL;		return READERR;    } 		This->Status = ALLDONE;	    Disconnect();    close(DataSock);	    return FTPOK;}uerr_t TFtpCli :: GetFileChunk(TThread * This){    uerr_t err;	FILE *fp = NULL;	unsigned char PasvAddr[6];	   	int DataSock;	int CtrlSock;    	/*     * set the thread attributes      */    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);	    if (This->Status == ALLDONE)    {		gettimeofday(&This->BeginTime, NULL);		return FTPOK;    }	This->Task->LockThread(This->Task);    This->Status = CONNECTING;    This->Task->BroadcastCond(This->Task);    This->Task->UnlockThread(This->Task);	err = Connect();    if (err != FTPOK)    {		if (err == FTPCONREFUSED)		{	    	Disconnect();	    	This->Status = CONREJECT;	    	return err;		} 		else		{	    	ShowMsg("Error connecting to %s", This->u->HostName);	    	This->Status = REMOTEFATAL;	    	return err;		}    }    ShowMsg("Connect Ok");	 	CtrlSock = CtrlSkp->GetSockfd();	if(UserName == NULL)		UserName = DEFAULT_FTP_USER;				    if(PassWord == NULL)		PassWord = DEFAULT_FTP_PASSWD;	    ShowMsg("Logging in as user %s password %s", UserName, PassWord);    This->Status = LOGGININ;    	err = Login();    if (err != FTPOK)    {		if (err == FTPLOGREFUSED)		{	    	Disconnect();	    	This->Status = LOGINFAIL;	    	return err;		}		else		{	    	ShowMsg("Login Failed");	    	Disconnect();	    	This->Status = REMOTEFATAL;	    	return err;		}  	} 	ShowMsg("Login Ok");	if(IsBinary)	{    	err = Binary();    	if (err != FTPOK)    	{			ShowMsg("Binary Failed");			Disconnect();			This->Status = REMOTEFATAL;			return err;    	} 		ShowMsg("Binary OK");	}	if (HostDirName)    {		err = Cwd(HostDirName);		if (err != FTPOK)		{	    	ShowMsg("CWD failed to change to directory %s", HostDirName);	    	Disconnect();	    	This->Status = REMOTEFATAL;	    	return err;		} 	    		ShowMsg("CWD OK");    }	else	{		ShowMsg("CWD is not needed");	}    if(IsPasv == true)    {		err = Pasv(PasvAddr);				if (err == FTPNOPASV || err == FTPINVPASV)		{	    	ShowMsg("Server doesn't seem to support PASV");	    	IsPasv = false;		}		if (err == FTPOK)			{	    	char dhost[256];	    	unsigned short dport;	    				sprintf(dhost, "%d.%d.%d.%d", PasvAddr[0], PasvAddr[1], 												PasvAddr[2], PasvAddr[3]);				    	dport = (PasvAddr[4] << 8) + PasvAddr[5];					if(DataSkp != NULL)			{				close(DataSkp->GetSockfd());				delete DataSkp;			}			DataSkp = new TSocketCli(dhost);			err = DataSkp->Connect(dport);			//DataSock = DataSkp->GetSockfd();							    	if (err != NOCONERROR)	    	{				ShowMsg("Error while connecting, \								according to servers PASV info");								close(CtrlSock);				This->Status = REMOTEFATAL;				return err;	    	}		}    }     if (IsPasv == false)    {		err = GetListenSocket();		if (err != FTPOK)		{	    	ShowMsg("listen failed");	    	Disconnect();	    	This->Status = REMOTEFATAL;	    	return err;		}    }    	err = Rest(This->RemoteStartPos);    if (err != FTPOK)    {		ShowMsg("REST failed");		Disconnect();		This->Status = REMOTEFATAL;		return err;    }    ShowMsg("REST ok");    err = Retr(HostFileName);    if (err != FTPOK)    {		ShowMsg("RETR failed");		Disconnect();		This->Status = REMOTEFATAL;		return err;    }    ShowMsg("RETR OK");    if(IsPasv == false)	    {		err = ListenSkp->Accept(&DataSock);		if (err != ACCEPTOK)		{	    	Disconnect();	    	This->Status = REMOTEFATAL;	    	return err;		}    }	err = RetrFileKnownSize(This);	return err;}uerr_t TFtpCli :: GetFileToEnd(TThread * This){    uerr_t err;	unsigned char PasvAddr[6];		int DataSock;	int ListenSock;	int CtrlSock; 		/* set the thread attributes */    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);    	/* if there is nothing to download then return */    if (This->Status == ALLDONE)    {		gettimeofday(&This->BeginTime, NULL);		return FTPOK;    }	This->Task->LockThread(This->Task);    This->Status = CONNECTING;    This->Task->BroadcastCond(This->Task);    This->Task->UnlockThread(This->Task);    err = Connect();    if (err != FTPOK)    {		if (err == FTPCONREFUSED)		{	    	Disconnect();	    	This->Status = CONREJECT;	    	return err;		} 		else		{	    	ShowMsg("Error connecting to %s", This->u->HostName);	    	This->Status = REMOTEFATAL;	    	return err;		}    }    ShowMsg("Connect Ok");		CtrlSock = CtrlSkp->GetSockfd();	if(UserName == NULL)		UserName = DEFAULT_FTP_USER;				    if(PassWord == NULL)		PassWord = DEFAULT_FTP_PASSWD;    ShowMsg("Logging in as user %s password %s", UserName, PassWord);	    This->Status = LOGGININ;	    err = Login();    if (err != FTPOK)    {		if (err == FTPLOGREFUSED)		{	    	Disconnect();	    	This->Status = LOGINFAIL;	    	return err;		}		else		{	    	ShowMsg("Login Failed");	    	Disconnect();	    	This->Status = REMOTEFATAL;	    	return err;		}  	} 	ShowMsg("Login Ok");	if(IsBinary)	{    	err = Binary();    	if (err != FTPOK)    	{			ShowMsg("Binary Failed");			Disconnect();			This->Status = REMOTEFATAL;			return err;    	} 		ShowMsg("Binary OK");	}	if (HostDirName)    {		err = Cwd(HostDirName);		if (err != FTPOK)		{	    	ShowMsg("CWD failed to change to directory %s", HostDirName);	    	Disconnect();	    	This->Status = REMOTEFATAL;	    	return err;		} 	    		ShowMsg("CWD OK");    } 	ShowMsg("CWD is not needed");    if (IsPasv == true)    {		err = Pasv(PasvAddr);		if (err == FTPNOPASV || err == FTPINVPASV)		{	    	ShowMsg("Server doesn't seem to support PASV");	    	IsPasv = false;		}		if (err == FTPOK)			{	    	char dhost[256];	    	unsigned short dport;	    				sprintf(dhost, "%d.%d.%d.%d", PasvAddr[0], PasvAddr[1], 												PasvAddr[2], PasvAddr[3]);				    	dport = (PasvAddr[4] << 8) + PasvAddr[5];						if(DataSkp != NULL)			{				close(DataSkp->GetSockfd());	    		delete DataSkp;			}			DataSkp = new TSocketCli(dhost);			err = DataSkp->Connect(dport);			//DataSock = DataSkp->GetSockfd();				    	if (err != NOCONERROR)	    	{				ShowMsg("Error while connecting, \								according to servers PASV info");				Disconnect();				This->Status = REMOTEFATAL;				return err;	    	}		}     }     if (IsPasv == false)    {		err = GetListenSocket();		if (err != FTPOK)		{	    	ShowMsg("listen failed");	    	Disconnect();	    	This->Status = REMOTEFATAL;	    	return err;		}    }    if (This->RemoteStartPos > 0 && This->u->ResumeSupport == true)    {		err = Rest(This->RemoteStartPos);		if (err != FTPOK)		{	    	ShowMsg("REST failed");	   	 	Disconnect();	    	This->Status = REMOTEFATAL;	    	return err;		}		ShowMsg("REST OK");    }    err = Retr(HostFileName);    if (err != FTPOK)    {		ShowMsg("RETR failed");		Disconnect();		This->Status = REMOTEFATAL;		return err;    }    if (IsPasv == false)	    {		err = ListenSkp->Accept(&DataSock);		if (err != ACCEPTOK)		{	    	Disconnect();	    	This->Status = REMOTEFATAL;	    	return err;		}    }	if(This->u->FileSize == -1)		err = RetrFileUnknownSize(This);	else		err = RetrFileKnownSize(This);	return err;}/* * Gets Size about the file from the ftp server */uerr_t TFtpCli :: Size(TUrl * u){    uerr_t err;	char szBuffer[FTP_BUF_SIZE];	int CtrlSock = CtrlSkp->GetSockfd(); 	    if (!HostFileName || !(*HostFileName))    {		ShowMsg("No file specified.");		return FILEBADFILE ;    }	    err = Cwd(HostFileName);    if (err == FTPOK)    {		ShowMsg("you must be specify a FileName");		return FTPOK;    }     sprintf(szBuffer, "SIZE %s\r\n", HostFileName);	    err = SendMsg(CtrlSock, szBuffer, strlen(szBuffer));    if (err != FTPOK)		return err;    err = GetReply(CtrlSock, szBuffer);	    if (err != FTPOK)		return err;    if (*szBuffer == '2')	    {		sscanf(szBuffer + 3, "%ld", &u->FileSize);		return FTPOK;    } 	else if (*szBuffer == '5')  /** A error hapenned */    {		if (strstr(szBuffer, "o such file")	    	|| strstr(szBuffer, "o Such File")	    	|| strstr(szBuffer, "ot found")	    	|| strstr(szBuffer, "ot Found"))	    return FTPNSFOD;    }}/*uerr_t TFtpCli :: SearchMirrorSite(TThread * This){}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -