- 论坛徽章:
- 0
|
// FTP.cpp : 定义控制台应用程序的入口点。
//
//=======================
//演示代码,没有错误处理,尽量简化了流程
//=========================
#include "stdafx.h"
#include <winsock.h>
#include <windows.h>
#include <stdio.h>
#pragma comment (lib,"Ws2_32"
//====以下是STL库
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
//因为是演示代码,所以申明了全局变量,请不要效仿
char Buff[1024];
SOCKET listenFD=NULL;
//================================
int recvbuff()
{
ZeroMemory(Buff,1024); //清0
int ret = recv(listenFD,Buff,1024,0);
printf(Buff);
return 0;
}
int main(int argc, char *argv[])
{
struct sockaddr_in my;
my.sin_family=AF_INET;
my.sin_addr.s_addr=inet_addr("192.168.18.119" ;
my.sin_port=htons(21);
WSADATA wsadata;
BOOL ThreadFlag=FALSE;
DWORD ThreadID=0;
int nRet=0;
nRet=WSAStartup(MAKEWORD(2,2),&wsadata); //初始化
listenFD=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
while (1)
{
nRet=connect(listenFD,(struct sockaddr*)&my,sizeof (struct sockaddr));
if (nRet!=SOCKET_ERROR)
{
break;
}
}
recvbuff(); //接收服务器版本信息
//==================================
char user[] = "USER admin\r\n";
char pass[] = "admin\r\n";
send(listenFD,user,sizeof(user),0);
recvbuff();
//==========================================
send(listenFD,pass,sizeof(pass),0);
recvbuff();
//=================================
char type[] = "TYPE I\r\n";
send(listenFD,type,sizeof(type),0); //更改传输类型为二进制
recvbuff();
//==========================================
//更改路径命令是 CWD
//================================
char pasv[] = " ASV\r\n";
send(listenFD,pasv,sizeof(pasv),0); //更改传输类型为二进制
recvbuff();
//=======================================
//以下代码摘自我的FTP客户端,使用了 string 对象,
//作用是处理服务器发回的 PASV 信息,得到把其中的IP和端口
//发回的格式为 227 Entering Passive Mode (192,168,18,119,11,7 ..
// 192,168,18,119 = 192.168.18.119
// 端口 = 11*256 + 78
//========================================
string ifstr = Buff; //把返回信息传给 string 对像,string 是STL中的字符串对象
string::size_type pos = 0; //长度,当整型吧,size_type是为了跨平台
string::size_type slen = ifstr.find("(" +1; // find 是指查找字符 "(" 的位置,返回长度
string::size_type dlen = 0 ;
int i = 0 ;
for( i ; i < 4 ; i++) //把IP地址中的 "," 换成 "."
{
dlen = ifstr.find(",",dlen);
ifstr.replace(dlen,1,"." ;
dlen++;
}
string ip = ifstr.substr(slen,dlen-slen-1); //把IP地址提出来
//==================================== //把端口提出来
string temport;
u_short uport;
slen = dlen;
dlen = ifstr.find("," ;
temport = ifstr.substr( slen , dlen - slen); //slen 起始地址,第二参数表示 以第一个地址copy出的字节数
uport = atoi( temport.c_str()) * 256 ;
//=====================================
slen = dlen + 1;
dlen = ifstr.find(" ",slen) ;
temport = ifstr.substr(slen,dlen - slen);
uport += atoi( temport.c_str());
//====================================
//分析返回的PASV信息完成,开始数据通道连接
//===================================
SOCKET ssock=NULL;
ssock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
struct sockaddr_in server;
server.sin_family=AF_INET;
server.sin_addr.s_addr=inet_addr(ip.c_str());
server.sin_port=htons(uport);
while (1)
{
nRet=connect(ssock,(struct sockaddr*)&server,sizeof (struct sockaddr));
if (nRet!=SOCKET_ERROR)
{
break;
}
}
printf("数据通道连接成功\n" ;
//==============================================
//==========================================
char stor[] = "STOR 测试.rar\r\n"; //上传文件
send(listenFD,stor,sizeof(stor),0);
recvbuff();
//=======================================
FILE *fp = NULL; //打开文件
fp = fopen( "c:\\测试.rar","rb" ; //只读打开二进制文件
//============================================
char filebuff[1024] ; //发送文件缓冲
long ret; //实际发送的字节数
printf("开始发送文件......" ;
while( fread(filebuff,1,1024,fp) ) //接收文件只到全部读完
{
slen = 1024;
while( slen ) //不停发送,只到全部发送完成
{
ret = send(ssock,filebuff,1024,0);
Sleep(0);
slen -= ret;
}
ZeroMemory(filebuff,1024);
}
closesocket(ssock);
printf("发送完成" ;
return 0;
} |
|