C++实现FTP服务器.docx
- 文档编号:23927709
- 上传时间:2023-05-22
- 格式:DOCX
- 页数:23
- 大小:65.62KB
C++实现FTP服务器.docx
《C++实现FTP服务器.docx》由会员分享,可在线阅读,更多相关《C++实现FTP服务器.docx(23页珍藏版)》请在冰豆网上搜索。
C++实现FTP服务器
准备工作VC6.0添加ws2_32.lib到工程,如下图操作:
1.首先添加winsock库到工程
2.添加lib库文件
3.添加ws2_32.lib切记用空格隔开
4.点击OK即可
源代码:
FTP_Client:
#pragmacomment(lib,"ws2_32.lib")
#include
#include
#include
#include
#include
#include
#defineTRAN_SUCCESS1//传输成功
#defineSOCK_WSA_ERR(-1)//启动winsock库失败
#defineSOCK_CRSOCK_ERR(-2)//创建套接字失败
#defineSOCK_BIND_ERR(-3)//绑定端口失败
#defineSOCK_LISTEN_ERR(-4)//监听失败
#defineSOCK_ACCEPT_ERR(-5)//等待连接失败
#defineSOCK_SEND_ERR(-6)//发送数据失败
#defineSOCK_CLOSE_ERR(-7)//关闭SOCKET失败
#defineSOCK_RECVE_ERR(-8)//接受数据失败
#defineSOCK_CONNECT_ERR(-10)
#defineFILE_ERR(-9)//文件错误
#defineOther_ERR(0)//其他不明原因
#defineSVR_PORT6000//服务器端口
#defineSEND_BUFFER_SIZE4096//每次发送大小
#defineRECV_BUFFER_SIZE4096//每次发送大小
structFileinfo
{
charfileName[50];//文件名
intfileBlock;//文件分块大小
intBlockNum;//文件块数量
unsignedlongfileSize;//文件总大小
};
intRecevData(SOCKETs);
intClient(char*fileName);
voidPrintReturn(intnRet);
intClient(char*strIP)
//intClient()
//intClient(char*fileName)
{
intnResult=0;
//1、启动Winsock:
对WinsockDLL进行初始化,协商Winsock的版本支持并分配必要的资源。
(服务器端和客户端)
WORDwVersion=MAKEWORD(2,0);//wversion为winsock库的版本,高位字节为副版本,地位字节为主版本
WSADATAwsData;
nResult=WSAStartup(wVersion,&wsData);//加载winsock库,wsData参数是指向LPWSADATA结构的指针
if(nResult!
=0)
{
returnSOCK_WSA_ERR;
}
if(LOBYTE(wsData.wVersion)!
=2||
HIBYTE(wsData.wVersion)!
=0)
{
WSACleanup();
//return;
exit(0);
}
//2、创建套接字:
(服务器端和客户端)
SOCKETs=socket(AF_INET,SOCK_STREAM,0);//创建套接字
if(s==INVALID_SOCKET)
{
returnSOCK_CRSOCK_ERR;//错误处理
}
/*
unsignedlonguladdr;
uladdr=inet_addr("127.0.0.1");
//sock=socket(AF_INET,SOCK_STREAM,0);
sockaddr_insa;
memset(&sa,0,sizeof(sa));
sa.sin_family=AF_INET;
sa.sin_port=htons(5150);
sa.sin_addr.S_un.S_addr=uladdr;
nResult=connect(s,(constsockaddr*)&sa,sizeof(sa));
//4、套接字的连结:
将两个套接字连结起来准备通信。
(客户端)
*/
/*intconnect(SOCKETs,conststructsockaddrFAR*name,intnamelen)
s为欲连结的已创建的套接字。
name为欲连结的socket地址。
namelen为socket地址的结构的长度。
*/
unsignedlonguladdr;
uladdr=inet_addr(strIP);
//uladdr=inet_addr("192.168.2.79");//此处设定的是Server端IP地址
//uladdr=inet_addr("127.0.0.1");
sockaddr_inaddr;
memset(&addr,0x00,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_port=htons(SVR_PORT);//保证字节顺序
//addr.sin_addr.s_addr=htonl(uladdr);//保证字节顺序**********这种写法很奇怪*************//
addr.sin_addr.S_un.S_addr=uladdr;
nResult=connect(s,(sockaddr*)&addr,sizeof(sockaddr));
if(nResult<0)
{
returnSOCK_CONNECT_ERR;//错误处理
}
/************************/
charRecvBuf[100];
recv(s,RecvBuf,100,0);
printf("%s\n",RecvBuf);
//charSendFileName[100];
//send(s,fileName,strlen(fileName)+1,0);
/************************/
//6、套接字的数据接收:
(客户端)
nResult=RecevData(s);
if(nResult<0)
{
returnnResult;//错误处理
}
//7、关闭套接字:
释放所占有的资源。
(服务器端和客户端)
nResult=closesocket(s);
if(nResult<0)
{
returnSOCK_CLOSE_ERR;//错误处理
}
returnTRAN_SUCCESS;
}
//---------------------------------------------------------------------------------
intRecevData(SOCKETs)
{
FILE*stream;
structFileinfofileinfo;
intnRet=0;
//unsignedlongdataLength,cbBytesRet,cbLeftToReceive;
unsignedlongdataLength,cbLeftToReceive;
BYTE*recdData=NULL;
memset(&fileinfo,0x00,sizeof(fileinfo));
nRet=recv(s,(char*)&fileinfo,sizeof(fileinfo),0);
if(nRet==SOCKET_ERROR)
{
returnSOCK_RECVE_ERR;
}
if((stream=fopen(fileinfo.fileName,"wb"))==NULL)
{
returnFILE_ERR;
}
//char*tt;
//nRet=send(s,(char*)"OK",sizeof("OK"),0);
dataLength=fileinfo.fileSize;
recdData=newbyte[RECV_BUFFER_SIZE];
cbLeftToReceive=dataLength;
intii=0;
do
{
intiiGet,iiRecd;
iiGet=(cbLeftToReceive cbLeftToReceive: RECV_BUFFER_SIZE; iiRecd=recv(s,(char*)recdData,iiGet,0); //testforerrorsandgetoutiftheyoccurred if(iiRecd==SOCKET_ERROR||iiRecd==0) { returnSOCK_RECVE_ERR; } printf("%d\n",ii++); fwrite(recdData,iiRecd,1,stream);//Writeit cbLeftToReceive-=iiRecd; send(s,(char*)&ii,sizeof(ii),0); } while(cbLeftToReceive>0); returnTRAN_SUCCESS; } voidPrintReturn(intnRet) { switch(nRet) { caseTRAN_SUCCESS: cout< caseSOCK_WSA_ERR: cout<<"SOCK_WSA_ERR"< caseSOCK_CRSOCK_ERR: cout<<"SOCK_CRSOCK_ERR"< caseSOCK_BIND_ERR: cout<<"SOCK_BIND_ERR"< caseSOCK_LISTEN_ERR: cout<<"SOCK_LISTEN_ERR"< caseSOCK_ACCEPT_ERR: cout<<"SOCK_ACCEPT_ERR"< caseSOCK_SEND_ERR: cout<<"SOCK_SEND_ERR"< caseSOCK_CLOSE_ERR: cout<<"SOCK_CLOSE_ERR"< caseSOCK_RECVE_ERR: cout<<"SOCK_RECVE_ERR"< caseSOCK_CONNECT_ERR: cout<<"SOCK_CONNECT_ERR"< caseFILE_ERR: cout<<"FILE_ERR"< caseOther_ERR: cout<<"Other_ERR"< default: cout<<"NOERROR"< } } intmain() { charip[]=""; //charfilename[]=""; cout<<"PleaseentertheFTPServer'sIPAddress: "< cin>>ip; //scanf("%s",ip); //cout<<"pleaseenterthefileyouwantontheFTP: "< //cin>>filename; //scanf("%s",filename); system("pause"); intnRet=Client(ip); PrintReturn(nRet); cout<<"RecvOK"< return0; } FTP_Server: #pragmacomment(lib,"ws2_32.lib") #include #include #include #include #include #defineTRAN_SUCCESS1//传输成功 #defineSOCK_WSA_ERR(-1)//启动winsock失败 #defineSOCK_CRSOCK_ERR(-2)//创建套接字失败 #defineSOCK_BIND_ERR(-3)//绑定端口失败 #defineSOCK_LISTEN_ERR(-4)//监听失败 #defineSOCK_ACCEPT_ERR(-5)//等待连接失败 #defineSOCK_SEND_ERR(-6)//发送数据失败 #defineSOCK_CLOSE_ERR(-7)//关闭SOCKET失败 #defineSOCK_RECVE_ERR(-8)//接受数据失败 #defineFILE_ERR(-9)//文件错误 #defineOther_ERR(0)//其他不明原因 #defineSVR_PORT6000//服务器端口 #defineSEND_BUFFER_SIZE4096//每次发送大小 structFileinfo { charfileName[50];//文件名 intfileBlock;//文件分块大小 intBlockNum;//文件块数量 unsignedlongfileSize;//文件总大小 }; boolGetLocalIP(charcaIpAddr[]); intFileSeReturn(intnRet); intFileSend(SOCKET*s,char*filename); voidPrintize(FILE*stream); longfilesize(FILE*stream); //---------------------------------------------------------------------------------- intServerSend(char*FileName) { intnResult=0; //1、启动Winsock: 对WinsockDLL进行初始化,协商Winsock的版本支持并分配必要的资源。 (服务器端和客户端) WORDwVersion=MAKEWORD(2,0); WSADATAwsData; nResult=WSAStartup(wVersion,&wsData); if(nResult! =0) { returnSOCK_WSA_ERR; } if(LOBYTE(wsData.wVersion)! =2|| HIBYTE(wsData.wVersion)! =0) { WSACleanup(); //return; exit(0); } //2、创建套接字: (服务器端和客户端) SOCKETs=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);//创建套接字 if(s==INVALID_SOCKET) { returnSOCK_CRSOCK_ERR;//错误处理 } //获取本地IP地址 /*charcaLocalIp[16]="127.0.0.1"; memset(caLocalIp,0x00,sizeof(caLocalIp)); if(! GetLocalIP(caLocalIp)) { returnSOCK_BIND_ERR; } */ //3、套接字的绑定: 将本地地址绑定到所创建的套接字上。 (服务器端和客户端) sockaddr_insockaddr; sockaddr.sin_family=AF_INET;//告知我们正在使用IP地址家族 sockaddr.sin_port=htons(SVR_PORT);//保证字节顺序 //sockaddr.sin_addr.s_addr=inet_addr(caLocalIp);//inet_addr将一个点式IP地址转换为32位的无符号整数 //sockaddr.sin_addr.s_addr=htonl(INADDR_ANY); sockaddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY); nResult=bind(s,(SOCKADDR*)&sockaddr,sizeof(SOCKADDR));//将套接字和一个特定IP地址绑定,s代表我们希望在上面等待客户机连接的那个套接字,addr为一个普通的缓冲区,在此处实际地填充一个地址缓冲区, if(nResult==SOCKET_ERROR) { returnSOCK_BIND_ERR;//错误处理 } //4、套接字的监听: (服务器端) nResult=listen(s,5);//最多5个连接 if(nResult==SOCKET_ERROR) { returnSOCK_LISTEN_ERR;//错误处理 } //5、套接字等待连接: : (服务器端) sockaddr_inclientaddr; SOCKETs_c; intlen; len=sizeof(clientaddr); //memset(cliaddr,0x00,len); s_c=accept(s,(SOCKADDR*)&clientaddr,&len); /*************/ charsendBuf[100]; sprintf(sendBuf,"Welcome%stoMyFTPServer",inet_ntoa(clientaddr.sin_addr)); send(s_c,sendBuf,strlen(sendBuf)+1,0); //charrecvBuf[100]; //recv(s_c,recvBuf,100,0); //printf("\nTheClientrequestFileis%s\n",recvBuf); /*************/ printf("AClientconnectedOK\n"); if(s_c<0) { returnSOCK_ACCEPT_ERR;//错误处理 } //6、套接字发送数据: (服务器端和客户端) nResult=FileSend(&s_c,FileName); if(nResult<0) { returnnResult;//错误处理 } //7、关闭套接字: 释放所占有的资源。 (服务器端和客户端) nResult=closesocket(s); if(nResult==SOCKET_ERROR) { returnSOCK_CLOSE_ERR;//错误处理 } returnTRAN_SUCCESS; } //----------------------------------------------------------------------------------------- //发送文件的程序 intFileSend(SOCKET*s,char*filename) { FILE*stream; structFileinfofileinfo; intnResult; if(! (stream=fopen(filename,"rb"))) { returnFILE_ERR; } //*******************************************组织文件基本信息准备发送**************************************** memset(&fileinfo,0x00,sizeof(fileinfo)); memcpy(&fileinfo.fileName,filename,sizeof(fileinfo.fileName)); fileinfo.fileBlock=SEND_BUFFER_SIZE; longsize=filesize(stream); if(size<=SEND_BUFFER_SIZE) fileinfo.BlockNum=1; else fileinfo.BlockNum=size/SEND_BUFFER_SIZE+1; fileinfo.fileSize=filesize(stream); unsignedin
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 实现 FTP 服务器