char *command;//命令字符串缓冲 int portForData;//数据端口信息 SOCKET socketData;//数据连接套接字 SOCKET socketControl;//控制连接套接字 sockaddr_in serveraddrData;//用于建立数据套接字参数,系统库参数 sockaddr_in serveraddr;//用于建立控制套接字参数,系统库参数 /******************************************* 返回cmdBuffer中有的应答码 cmdBuffer必须有返回信息
前提条件:cmdbuffer中尚存PASV命令的应答信息 用来获取cmdBuffer中的端口信息并进行转换 *******************************************/ int getCode() { int code = 100*(cmdBuffer[0]-'0')+10*(cmdBuffer[1]-'0')+(cmdBuffer[2]-'0'); return code; }
/******************************************* 初始化控制连接
初始化客户端,连接服务器,成功返回1
失败返回0,打印欢迎信息,server返回信息,IP *******************************************/ int interlizeSocket() { //建立与Socket库绑定 WSAStartup(MAKEWORD(2,2),&wsd); //创建流式Socket socketControl = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //填充本地Socket地址 serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(port); serveraddr.sin_addr.s_addr=inet_addr(ipAddress.c_str()); //向FTP服务器发送Connect请求 connect (socketControl, (sockaddr*)&serveraddr, sizeof(serveraddr)); //从FTP服务器获得Connect应答 if (recv(socketControl,cmdBuffer,512,0)) { cout<<\ //判断Connect请求的应答码 if(getCode() == 220) { memset (cmdBuffer,NULL,512); return 1; }
25 / 37
else closesocket(socketControl); memset (cmdBuffer,NULL,512); return 0; } memset (cmdBuffer,NULL,512); return 0; }
/**************************************** buffer:文件缓冲区
cmdBuffer:接收命令缓冲区 listBuffer:文件列表缓冲区
command:命令格式构造使用缓冲区 ip:ip地址,p:端口号
****************************************/ public: ftpClient(string ip,int p) { this->buffer = new char[4096]; memset (buffer,NULL,4096); this->cmdBuffer = new char[512]; memset (cmdBuffer,NULL,512); this->listBuffer = new char[4096]; memset (listBuffer,NULL,4096); this->command = new char[512]; memset (command,NULL,512); ipAddress = ip; port = p; cout<<\ if(interlizeSocket()==1) cout<<\ } ~ftpClient() { delete buffer; delete cmdBuffer; delete listBuffer; delete command; closesocket(socketControl); }
/**************************************** privatePart:固定部分如USER PASS 等 userPart:用户输入部分如Anonymous Direct等 标准格式
26 / 37
一般为
或
****************************************/ int setCommand(char* privatePart,char* userPart) { memset (command,NULL,strlen(command)); memcpy (command,privatePart,strlen(privatePart)); memcpy (command+strlen(privatePart),userPart,strlen(userPart)); memcpy (command+strlen(privatePart)+strlen(userPart),\ return 1; } int setCommand(char* privatePart) { memset(command,NULL,strlen(command)); memcpy(command,privatePart,strlen(privatePart)); memcpy (command+strlen(privatePart),\ return 1; }
/******************************************* 发送command中的命令
command中必须有格式化好的命令
*******************************************/ int sendCommand() { cout<<\ send(socketControl,command,strlen(command),0); memset(command,NULL,strlen(command)); return 1; }
/******************************************** 接收控制信息应答码
从socketControl接收信息读入cmdBuffer 成功返回代码,失败返回600.
********************************************/ int receiveCommand() { memset(cmdBuffer,NULL,strlen(cmdBuffer)); if(recv(socketControl,cmdBuffer,512,0)) { cout<<\ int temp = getCode(); return temp; }
27 / 37
return 600; }
/******************************************** socketData初始化,取PASV的返回信息,转化为int 建立socket,socketData信息储存在buffer 或listBuffer中,用于数据的传输。
条件:cmdBuffer中必须储存有PASV返回信息 ********************************************/ int getPort() { /************************************ 端口号分析相关,通过num数组读取3位 端口号,通过定位,转换2部分转换为int 型端口号。公式x.x.x.x.aaa.bbb::端口号 ::aaa*512+bbb(网上查得) 或将aaabbb转换为十进制相加(原为 十六进制) ************************************/ char* num = new char[3]; int flagA = 2; int flagB = 0; int temp; int j = 0; int i; int test; for(int i = 0;i<=511;i++) { if (cmdBuffer[i]==',') { flagB++; if(flagB==4) { temp = i; temp++; break; } } } i = temp; while (flagA>0) { if (cmdBuffer[i]>='0'&&cmdBuffer[i]<='9')
28 / 37

