📄 tftpclient.cpp
字号:
char buf[10240];
switch(cmd){
// 改名
case RENAME:{
snprintf(buf, sizeof(buf), (char*)"RNFR %s\r\n", cmdvalue );//rename from
int len=strlen(buf);
int ret = Write(m_hControlChannel,buf,&len);
if( ret < 0 || len != strlen(buf) ){
return -1;
}
ret = WaitResult(m_hControlChannel);
if(ret != 350){
return -1;
}
snprintf(buf, sizeof(buf), (char*)"RNTO %s\r\n", returnvalue );//rename to
if( FTPCommand(buf) != 0 )
return -1;
return 0;
}
// 获取远端文件状态
case STATCMD:{
snprintf(buf, sizeof(buf), (char*)"STAT %s\r\n", cmdvalue);
int len = strlen(buf);
int ret = Write(m_hControlChannel,buf,&len);
if( ret < 0 || len != strlen(buf)){
return -1;
}
ret= WaitResult(m_hControlChannel);
if(ret != 213){
return -1;
}
else {
m_strReplyBuffer[strlen(m_strReplyBuffer) - 1 ] = 0;
char* p = strchr(m_strReplyBuffer, '\n');
if( p == NULL )
return -1;
p++;
char* q = strrchr(m_strReplyBuffer, '\n');
if(q == NULL )
return -1;
*(q+1) = 0;
if( retmaxsize == 0 )
strcpy(returnvalue, p);
else
strncpy(returnvalue, p, retmaxsize);
return 0;
}
}
/* 改变服务器端当前路径 */
case CHDIR:
snprintf(buf,sizeof(buf),(char*)"CWD %s\r\n", cmdvalue);
return FTPCommand(buf);
// 获取远端文件的大小
case SIZE:{
snprintf(buf, sizeof(buf), (char*)"SIZE %s\r\n", cmdvalue);
int len=strlen(buf);
int ret = Write(m_hControlChannel,buf,&len);
if( ret<0||len!=strlen(buf)){
return -1;
}
ret= WaitResult(m_hControlChannel);
if(ret/100 != 2){
if( ret <= 0 )
return -1;
return FTP_E_FILE;
}
else {
char* p = strchr(m_strReplyBuffer, ' ');
if( p == NULL ) return -1;
while( *p > '9' || *p < '0') p++;
if( retmaxsize == 0 )
strcpy(returnvalue, p );
else
strncpy(returnvalue, p, retmaxsize);
return 0;
}
}
/* 改变服务器端路径为当前路径的父目录 */
case CDUP:
return FTPCommand("CDUP\r\n");
/* 删除服务器端指定文件 */
case DEL:
snprintf(buf,sizeof(buf),(char*)"DELE %s\r\n", cmdvalue);
return FTPCommand(buf);
/* 列出服务器端指定目录(默认为当前目录)的内容,并放入指定的文件中 */
case LS:
{
if(CreateListenSocket()) return -1;
if(cmdvalue==NULL)
{
strcpy(buf,"LIST\r\n");
}
else
{
snprintf(buf,sizeof(buf),(char*)"LIST %s\r\n", cmdvalue);
}
#ifdef _NLIST_
strcpy(buf,"NLST\r\n");
#endif
int len = strlen(buf);
int ret = Write(m_hControlChannel,buf,&len);
if(ret<0 || len != strlen(buf) ){
close(m_hListenSocket);
return -1;
}
ret=WaitResult(m_hControlChannel);
if(ret != 150){
close(m_hDataSocket);
close(m_hListenSocket);
return -1;
}
ret = Accept(m_hListenSocket,NULL,NULL);
close(m_hListenSocket);
if(ret > 0 ){
m_hDataSocket = ret;
}
else {
ret = WaitResult(m_hControlChannel);
if(ret > 500){
return -2;
}
return -1;
}
int fd;
if((fd = open(returnvalue, O_CREAT|O_TRUNC|O_RDWR, 0660))<0){
close(m_hDataSocket);
perror("open file");
return -1;
}
int timer=time(0);
int totallen=0;
int tmptime;
while(1){
tmptime=time(0);
if( tmptime >= timer + m_iMaxWaitTime ){
close(m_hDataSocket);
printf("time out %d seconds when get a remote file\n", m_iMaxWaitTime);
close(fd);
return -1;
}
len = 10240;
ret = Read(m_hDataSocket,buf,&len);
if( ret != 0 )
break;
else if( len == 0 )
continue;
timer=tmptime;
if(write(fd, buf, len) < len) {
perror("write file");
close(fd);
close(m_hDataSocket);
return -1;
}
totallen += len;
}
close(fd);
close(m_hDataSocket);
ret = WaitResult(m_hControlChannel);
if( ret == 226 ) return 0 ;
return -1;
}
/* 显示服务器端当前目录的绝对路径 */
case PWD:
if(FTPCommand("PWD\r\n"))return -1;
{
char* p1=strchr(m_strReplyBuffer,'\"');
*strchr(++p1,'\"')=0;
if( retmaxsize == 0 )
strcpy(returnvalue,p1);
else
strncpy(returnvalue, p1, retmaxsize);
}
return 0;
/* 在服务器端创建目录 */
case MKDIR:
snprintf(buf,sizeof(buf),(char*)"MKD %s\r\n", cmdvalue);
return FTPCommand(buf);
/* 在服务器端删除目录 */
case RMDIR:
snprintf(buf,sizeof(buf),(char*)"RMD %s\r\n", cmdvalue);
return FTPCommand(buf);
/* 获得服务器端系统类型 */
case SYSTYPE:
if(FTPCommand("SYST\r\n"))return -1;
*strstr(m_strReplyBuffer,"\r\n")=0;
if( retmaxsize == 0 )
strcpy(returnvalue,m_strReplyBuffer+4);
else
strncpy(returnvalue,m_strReplyBuffer+4, retmaxsize);
return 0;
default:
printf("valid command\n");
return -1;
}
}
/********************************************************
* function:FTPCommand
* purpose:发送FTP 命令到FTP Server
* return: FTP_SUCCEED 成功 , FTP_FAIL 失败
*
*********************************************************/
int TFTPClient::FTPCommand(const char* strCommand)
{
int len = strlen(strCommand);
int ret = Write(m_hControlChannel,(char*)strCommand,&len);
if( ret < 0 || len!=strlen(strCommand)){
return -1;
}
ret= WaitResult(m_hControlChannel);
if(ret/100 !=2){
return -1;
}
return 0;
}
/********************************************************
* function:FTPLogout
* purpose:退出登陆
* return:
*
*********************************************************/
void TFTPClient::FTPLogout()
{
FTPCommand("QUIT\r\n");
close(m_hControlChannel);
}
/*******************************************************
*
* 描述:主机字节序测试
* 返回:1-高端字节序,0-低端字节序
*
********************************************************/
int TFTPClient::IsBigOrder(){
union{
short s;
char c[sizeof(short)];
}un;
un.s = 0x0102;
/*printf("%s:",CPU_VENDOR_OS);*/
if(sizeof(short) >= 2) {
if( un.c[0] == 1 && un.c[1] == 2) {
//printf("big-endian\n");
return 1;
}
else if(un.c[0] == 2&& un.c[1] == 1) {
//printf("little-endian\n");
return 0;
}
else {
//printf("unknown\n");
return -1;
}
}
else {
printf("sizeof(short) = %d\n",sizeof(short));
return -1;
}
}
/* return: -1:写失败, 0 写成功 */
int TFTPClient::Write(int fd, char* buff, int *len)
{
fd_set writefds;
fd_set errfds;
struct timeval tv;
int ret;
FD_ZERO(&writefds);
FD_SET(fd,&writefds);
FD_ZERO(&errfds);
FD_SET(fd,&errfds);
tv.tv_sec=m_iTimeOut;
tv.tv_usec=0;
if( select(fd+1, NULL, &writefds, &errfds, &tv) ) {
if(FD_ISSET(fd, &errfds)) {
*len = 0;
return -1;
}
else if(FD_ISSET(fd, &writefds)) {
//如果FTP Server异常中断,会造成此处阻塞
ret = write(fd, buff, *len);
*len = 0;
if( ret > 0 ) {
*len = ret;
return 0;
}
else {
return -1;
}
}
}
return -1;
}
/*return : -1,失败,0,成功或者超时,1,EOF */
int TFTPClient::Read(int fd, char* buff, int *len)
{
fd_set readfds;
fd_set errfds;
struct timeval tv;
int ret;
FD_ZERO(&readfds);
FD_SET(fd,&readfds);
FD_ZERO(&errfds);
FD_SET(fd,&errfds);
tv.tv_sec = m_iTimeOut;
tv.tv_usec = 0;
if( select(fd+1, &readfds, NULL, &errfds, &tv) ) {
if(FD_ISSET(fd, &errfds)) {
*len = 0;
return -1;
}
if(FD_ISSET(fd, &readfds)) {
ret=read(fd, buff, *len);
*len = 0;
if( ret == 0)
return 1;
if( ret < 0)
return -1;
*len = ret;
return 0;
}
}
*len = 0;
return 0;
}
/* 等待连接,返回:0--超时,-1,错误,连接套接字 */
int TFTPClient::Accept(int fd,struct sockaddr* addr,int* len)
{
fd_set readfds;
fd_set errfds;
struct timeval tv;
FD_ZERO(&readfds);
FD_SET(fd,&readfds);
FD_ZERO(&errfds);
FD_SET(fd,&errfds);
tv.tv_sec=m_iTimeOut;
tv.tv_usec=0;
if(select(fd+1, &readfds, NULL, &errfds, &tv)) {
if(FD_ISSET(fd,&errfds)) {
return -1;
}else if(FD_ISSET(fd,&readfds)) {
#if defined(_AIX) || defined(__linux__)
return accept(fd, addr, (socklen_t *)len);
#else
return accept(fd, addr, len);
#endif
} else{
return 0;
}
}
return 0;
}
/* return -1:失败, 0,超时, 其他,返回应答数字*/
int TFTPClient::WaitResult(int fd)
{
int tmptime;
int ret;
memset(m_strReplyBuffer,0,sizeof(m_strReplyBuffer));
int totallen=0;
int len=1;
int timer=time(0);
while(1)
{
tmptime=time(0);
if(tmptime >= timer+m_iMaxWaitTime){
return 0;
}
//len=sizeof(m_strReplyBuffer)-totallen;
int Nlen=1;
ret = Read(fd, &m_strReplyBuffer[totallen], &Nlen);
#ifdef _DEBUG_
write(STDOUT_FILENO, &m_strReplyBuffer[totallen],1);
#endif
if(ret != 0)
return -1;
else if( Nlen == 0 )
continue;
totallen += Nlen;
/* 这里返回多行仔细考虑,多行时,第一行第四个字符是减号 */
if((m_strReplyBuffer[totallen-2] == '\r' && m_strReplyBuffer[totallen-1] == '\n')
||m_strReplyBuffer[totallen-1] == 0)
{
int retcode = atol( m_strReplyBuffer );
if( strlen( m_strReplyBuffer) < 4 || m_strReplyBuffer[3] != '-' )
{
//printf("result:%s\n", m_strReplyBuffer);
return atol(m_strReplyBuffer);
}
char* p = m_strReplyBuffer;
char* q;
while(GetLine(p, &q) == 0 )
{
if( strlen(q)>3 && *(q+3) == ' ' && atol(q) == retcode )
{
//printf("result:%s\n", m_strReplyBuffer);
return retcode;
}
p = q;
}/*while*/
}/*if*/
}/*while(1)*/
}
int TFTPClient::GetLine( char* src, char** nextline)
{
char* p = src;
for( ; *p != 0 ; p++ ) {
if( *p == '\n' && *(p+1) != 0 ) {
*nextline = p + 1;
return 0;
}
}
return -1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -