/*
* 版 本 号:v1.0
* 对任务及求解方法的描述部分:
* 输入描述:无
* 问题描述:无
* 程序输出:dir bye
* 问题分析:FTP客户端程序设计(主动模式)
* 算法设计:使用结构体
*/
#include <iostream>
#include <fstream>
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define IO_RCVALL _WSAIOW(IOC_VENDOR,1)
using namespace std;
unsigned short GetServerPort(char reply[])
{
char * part[6];
if(strtok(reply,"("))
{
for(int i=0;i<5;i++)
{
part[i]=strtok(NULL,",");
if(!part[i])
return 0;
}
part[5]=strtok(NULL,")");
if(!part[5])
return 0;
}
else
return 0;
unsigned short serverport;
serverport=unsigned short(atoi(part[4])*256+atoi(part[5]));
return serverport;
}
int main()
{
//****************************初始化socket***************************
WSADATA WSAData;
if(WSAStartup(MAKEWORD(2,2), &WSAData)!=0)
{
cout<<"启动失败"<<endl;
return -1;
}
//***************************创建原始socket***************************
SOCKET sock=socket(AF_INET,SOCK_STREAM,0);
if(sock==INVALID_SOCKET)
{
cout<<"socket创建失败";
return 0;
}
//****************************connect********************************
SOCKADDR_IN serveraddr; //设置结构体
serveraddr.sin_family=AF_INET;
serveraddr.sin_addr.s_addr=inet_addr("172.29.16.1"); //ftp服务器的ip地址
serveraddr.sin_port=htons(21);
if(connect(sock,(sockaddr *)&serveraddr,sizeof(serveraddr))==SOCKET_ERROR)
{
cout<<"connect failed"<<endl;
return -1;
}
//******************************接收数据*******************************
sockaddr_in dest_addr;
char icmp_data[5000]={'\0'};
int addr_len=sizeof(dest_addr);
int nrecv=recvfrom(sock,icmp_data,sizeof(icmp_data),0,(sockaddr *)&dest_addr,&addr_len);
if (nrecv<0)
{
cout<<"receive failed"<<endl;
closesocket(sock);
WSACleanup();
return -1;
}
else
{
cout<<icmp_data<<endl;
}
//****************************输入用户名********************************
cout<<"ftp>User: " ;
gets(icmp_data);
char temp[100];
memset(temp,'\0',100);
memcpy(temp,"USER ",strlen("USER "));
memcpy(temp+strlen("USER "),icmp_data,strlen(icmp_data));
memcpy(temp+strlen("USER ")+strlen(icmp_data),"\r\n",2);
int nsend=sendto(sock,temp,sizeof(temp),0,(sockaddr *)&dest_addr,sizeof(dest_addr));
if (nsend<0)
{
cout<<"send failed"<<endl;
return -1;
}
memset(icmp_data,'\0',5000);
nrecv=recvfrom(sock,icmp_data,sizeof(icmp_data),0,(sockaddr *)&dest_addr,&addr_len);
if (nrecv<0)
{
cout<<"receive failed"<<endl;
closesocket(sock);
WSACleanup();
return -1;
}else
{
cout<<icmp_data<<endl;
}
//******************************输入密码**************************
cout<<"ftp>Password: ";
gets(icmp_data);
memset(temp,'\0',100);
memcpy(temp,"PASS ",strlen("PASS "));
memcpy(temp+strlen("PASS "),icmp_data,strlen(icmp_data));
memcpy(temp+strlen("PASS ")+strlen(icmp_data),"\r\n",2);
nsend=sendto(sock,temp,sizeof(temp),0,(sockaddr *)&dest_addr,sizeof(dest_addr));
if (nsend<0)
{
cout<<"send failed"<<endl;
return -1;
}
memset(icmp_data,'\0',5000);
nrecv=recvfrom(sock,icmp_data,sizeof(icmp_data),0,(sockaddr *)&dest_addr,&addr_len);
if (nrecv<0)
{
cout<<"receive failed"<<endl;
closesocket(sock);
WSACleanup();
return -1;
}else
{
cout<<icmp_data<<endl;
}
//*******************************************************************************************
while(true)
{
cout<<"ftp> ";
memset(icmp_data,0,5000);
gets(icmp_data);
//**********************quit*****************************************************************
if(strcmp(icmp_data,"bye")==0)
{
memset(temp,'\0',100);
memcpy(temp,"QUIT",strlen("QUIT"));
memcpy(temp+strlen("QUIT"),"\r\n",2);
nsend=sendto(sock,temp,strlen(temp),0,(sockaddr *)&dest_addr,sizeof(dest_addr));
if (nsend<0)
{
cout<<"send failed"<<endl;
return -1;
}
memset(icmp_data,0,100);
nsend=recvfrom(sock,icmp_data,sizeof(icmp_data),0,(sockaddr *)&dest_addr,&addr_len);
if (nrecv<0)
{
cout<<"receive failed"<<endl;
closesocket(sock); //关闭套接字描述符
WSACleanup(); //清空库
return -1;
}
else
{
cout<<icmp_data<<endl;
}
}
//****************************判断是否输入DIR*************************************************
if(strcmp(icmp_data,"dir")==0)
{
//**************************获取服务器的端口号************************************************
unsigned short s_port=0;
sockaddr_in local_addr;
int sin_size=sizeof(local_addr);
getsockname(sock, (struct sockaddr*)&local_addr, &sin_size);
s_port=ntohs(local_addr.sin_port);
//*************************数据连接方式PORT***************************************************
/* int p1=s_port/256;
int p2=s_port%256;
char tt[2];
tt[0]=((p1/10)+48);
tt[1]=((p1%10)+48);
char ss[2];
ss[0]=((p2/10)+48);
ss[1]=((p2%10)+48);
memset(temp,'\0',100);
memcpy(temp,"PORT 172,29,41,8,5,45",strlen("PORT 172,29,41,8,5,45"));
memcpy(temp+strlen("PORT 172,29,41,8,5,45"),tt,strlen(tt));
memcpy(temp+strlen("PORT 172,29,41,8,5,45")+strlen(tt),",",1);
memcpy(temp+strlen("PORT 172.29.41.8")+strlen(tt)+1,ss,strlen(ss));
*/
//***************************创建数据data_socket***********************************************
SOCKET data_sock=socket(AF_INET,SOCK_STREAM,0);
if(data_sock==INVALID_SOCKET)
{
cout<<"socket创建失败";
return 0;
}
SOCKADDR_IN serveraddr2; //设置结构体
serveraddr2.sin_family=AF_INET;
serveraddr2.sin_addr.s_addr=inet_addr("172.29.41.253"); //ftp服务器的ip地址
serveraddr2.sin_port=htons(52428); // 动态获取ftpserver服务器端口号
int serveraddr2_len=sizeof(serveraddr2);
//*****************************bind和listen*****************************************************
bind(data_sock,(struct sockaddr *)&serveraddr2,serveraddr2_len);
struct sockaddr_in client_name;
int length = sizeof(client_name);
listen(data_sock, 52428);
memset(temp,'\0',100);
memcpy(temp,"PORT 172,29,41,8,5,45",strlen("PORT 172,29,41,8,5,45"));
memcpy(temp+strlen("PORT 172,29,41,8,5,45"),"\r\n",2);
nsend=sendto(sock,temp,strlen(temp),0,(sockaddr *)&dest_addr,sizeof(dest_addr));
if (nsend<0)
{
cout<<"send failed"<<endl;
return -1;
}
memset(icmp_data,0,5000);
//*****************************收到 200 potr command successful*********************************
nrecv=recvfrom(sock,icmp_data,sizeof(icmp_data),0,(sockaddr *)&dest_addr,&addr_len);
if (nrecv<0)
{
cout<<"receive failed"<<endl;
closesocket(sock);
WSACleanup();
return -1;
}
else
{
cout<<icmp_data<<endl;
}
//***********************************************************************************************
memset(temp,'\0',100);
memcpy(temp,"LIST ",strlen("LIST "));
memcpy(temp+strlen("LIST"),"\r\n",2);
nsend=sendto(sock,temp,strlen(temp),0,(sockaddr *)&dest_addr,sizeof(dest_addr));
if (nsend<0)
{
cout<<"send failed"<<endl;
return -1;
}
memset(icmp_data,0,1024);
nrecv=recvfrom(sock,icmp_data,sizeof(icmp_data),0,(sockaddr *)&dest_addr,&addr_len);
if (nrecv<0)
{
cout<<"receive failed"<<endl;
closesocket(sock);
return -1;
}
else
{
cout<<icmp_data<<endl;
}
data_sock = accept(sock,(struct sockaddr *)&client_name,&length);
}
}
//****************************关闭套接字********************************************************
closesocket(sock); //关闭套接字描述符
WSACleanup(); //清空库
return 0;
}