FTPserver部分代码.docx
- 文档编号:26247611
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:40
- 大小:24.45KB
FTPserver部分代码.docx
《FTPserver部分代码.docx》由会员分享,可在线阅读,更多相关《FTPserver部分代码.docx(40页珍藏版)》请在冰豆网上搜索。
FTPserver部分代码
//MiniFtpServer.cpp:
Definestheentrypointfortheconsoleapplication.
#include"stdafx.h"
#include
#include
#include
#defineWSA_RECV0
#defineWSA_SEND1
#defineDATA_BUFSIZE8192
#defineMAX_NAME_LEN128
#defineMAX_PWD_LEN128
#defineMAX_RESP_LEN1024
#defineMAX_REQ_LEN256
#defineMAX_ADDR_LEN80
#defineFTP_PORT21//FTP控制端口
#defineDATA_FTP_PORT20//FTP数据端口
#defineUSER_OK331
#defineLOGGED_IN230
#defineLOGIN_FAILED530
#defineCMD_OK200
#defineOPENING_AMODE150
#defineTRANS_COMPLETE226
#defineCANNOT_FIND550
#defineFTP_QUIT221
#defineCURR_DIR257
#defineDIR_CHANGED250
#defineOS_TYPE215
#defineREPLY_MARKER504
#definePASSIVE_MODE227
#defineFTP_USER"toldo"
#defineFTP_PASS"toldo"
#defineDEFAULT_HOME_DIR"C:
\\TEMP"
#defineMAX_FILE_NUM1024
#defineMODE_PORT0
#defineMODE_PASV1
#definePORT_BIND1821
typedefstruct{
CHARbuffRecv[DATA_BUFSIZE];
CHARbuffSend[DATA_BUFSIZE];
WSABUFwsaBuf;
SOCKETs;
WSAOVERLAPPEDo;
DWORDdwBytesSend;
DWORDdwBytesRecv;
intnStatus;
}SOCKET_INF,*LPSOCKET_INF;
typedefstruct{
TCHARszFileName[MAX_PATH];
DWORDdwFileAttributes;
FILETIMEftCreationTime;
FILETIMEftLastAccessTime;
FILETIMEftLastWriteTime;
DWORDnFileSizeHigh;
DWORDnFileSizeLow;
}FILE_INF,*LPFILE_INF;
DWORDWINAPIProcessTreadIO(LPVOIDlpParam);
BOOLWelcomeInfo(SOCKETs);
intLoginIn(LPSOCKET_INFpSocketInfo);
intSendRes(LPSOCKET_INFpSI);
intRecvReq(LPSOCKET_INFpSI);
intDealCommand(LPSOCKET_INFpSI);
intGetFileList(LPFILE_INFpFI,UINTnArraySize,constchar*szPath);
char*GetLocalAddress();
char*HostToNet(char*szPath);
char*NetToHost(char*szPath);
char*RelativeDirectory(char*szDir);
char*AbsoluteDirectory(char*szDir);
DWORDg_dwEventTotal=0;
DWORDg_index;
WSAEVENTg_events[WSA_MAXIMUM_WAIT_EVENTS];
LPSOCKET_INFg_sockets[WSA_MAXIMUM_WAIT_EVENTS];
CRITICAL_SECTIONg_cs;
charg_szLocalAddr[MAX_ADDR_LEN];
BOOLg_bLoggedIn;
//主函数,控制台程序开始的地方
voidmain(void)
{
WSADATAwsaData;
SOCKETsListen,sAccept;
SOCKADDR_INinetAddr;
DWORDdwFlags;
DWORDdwThreadId;
DWORDdwRecvBytes;
INTnRet;
InitializeCriticalSection(&g_cs);
if((nRet=WSAStartup(0x0202,&wsaData))!
=0){
printf("错误:
WSAStartupfailedwitherror%d\n",nRet);
return;
}
//先取得本地地址
sprintf(g_szLocalAddr,"%s",GetLocalAddress());
if((sListen=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,
WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)
{
printf("错误:
Failedtogetasocket%d\n",WSAGetLastError());
WSACleanup();
return;
}
inetAddr.sin_family=AF_INET;
inetAddr.sin_addr.s_addr=htonl(INADDR_ANY);
inetAddr.sin_port=htons(FTP_PORT);
if(bind(sListen,(PSOCKADDR)&inetAddr,sizeof(inetAddr))==SOCKET_ERROR)
{
printf("错误:
bind()failedwitherror%d\n",WSAGetLastError());
return;
}
if(listen(sListen,SOMAXCONN))
{
printf("错误:
listen()failedwitherror%d\n",WSAGetLastError());
return;
}
printf("MiniFtpserver已经启动\n");
printf("MiniFtpserver开始侦听\n");
if((sAccept=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,
WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)
{
printf("错误:
Failedtogetasocket%d\n",WSAGetLastError());
return;
}
//创建第一个手动重置对象
if((g_events[0]=WSACreateEvent())==WSA_INVALID_EVENT)
{
printf("错误:
WSACreateEventfailedwitherror%d\n",WSAGetLastError());
return;
}
//创建一个线程处理请求
if(CreateThread(NULL,0,ProcessTreadIO,NULL,0,&dwThreadId)==NULL)
{
printf("错误:
CreateThreadfailedwitherror%d\n",GetLastError());
return;
}
g_dwEventTotal=1;
while(TRUE)
{
//处理入站连接
if((sAccept=accept(sListen,NULL,NULL))==INVALID_SOCKET)
{
printf("错误:
acceptfailedwitherror%d\n",WSAGetLastError());
return;
}
//回传欢迎消息
if(!
WelcomeInfo(sAccept))break;
//设置ftp根目录
if(!
SetCurrentDirectory(DEFAULT_HOME_DIR))break;
//操作临界区,防止出错
EnterCriticalSection(&g_cs);
//创建一个新的SOCKET_INF结构处理接受的数据socket.
if((g_sockets[g_dwEventTotal]=(LPSOCKET_INF)
GlobalAlloc(GPTR,sizeof(SOCKET_INF)))==NULL)
{
printf("错误:
GlobalAlloc()failedwitherror%d\n",GetLastError());
return;
}
//初始化新的SOCKET_INF结构
charbuff[DATA_BUFSIZE];memset(buff,0,DATA_BUFSIZE);
g_sockets[g_dwEventTotal]->wsaBuf.buf=buff;
g_sockets[g_dwEventTotal]->wsaBuf.len=DATA_BUFSIZE;
g_sockets[g_dwEventTotal]->s=sAccept;
memset(&(g_sockets[g_dwEventTotal]->o),0,sizeof(OVERLAPPED));
g_sockets[g_dwEventTotal]->dwBytesSend=0;
g_sockets[g_dwEventTotal]->dwBytesRecv=0;
g_sockets[g_dwEventTotal]->nStatus=WSA_RECV;//接收
//创建事件
if((g_sockets[g_dwEventTotal]->o.hEvent=g_events[g_dwEventTotal]=
WSACreateEvent())==WSA_INVALID_EVENT)
{
printf("WSACreateEvent()failedwitherror%d\n",WSAGetLastError());
return;
}
//发出接受请求
dwFlags=0;
if(WSARecv(g_sockets[g_dwEventTotal]->s,
&(g_sockets[g_dwEventTotal]->wsaBuf),1,&dwRecvBytes,&dwFlags,
&(g_sockets[g_dwEventTotal]->o),NULL)==SOCKET_ERROR)
{
if(WSAGetLastError()!
=ERROR_IO_PENDING)
{
printf("错误:
WSARecv()failedwitherror%d\n",WSAGetLastError());
return;
}
}
g_dwEventTotal++;
//离开临界区
LeaveCriticalSection(&g_cs);
//使第一个事件有信号。
使工作者线程处理其他的事件
if(WSASetEvent(g_events[0])==FALSE)
{
printf("错误:
WSASetEventfailedwitherror%d\n",WSAGetLastError());
return;
}
}
}
//工作者线程处理函数
DWORDWINAPIProcessTreadIO(LPVOIDlpParameter)
{
DWORDdwFlags;
LPSOCKET_INFpSI;
DWORDdwBytesTransferred;
DWORDi;
//处理异步的WSASend,WSARecv等请求等
while(TRUE)
{
if((g_index=WSAWaitForMultipleEvents(g_dwEventTotal,g_events,FALSE,
WSA_INFINITE,FALSE))==WSA_WAIT_FAILED)
{
printf("错误:
WSAWaitForMultipleEventsfailed%d\n",WSAGetLastError());
return0;
}
if((g_index-WSA_WAIT_EVENT_0)==0)
{
WSAResetEvent(g_events[0]);
continue;
}
pSI=g_sockets[g_index-WSA_WAIT_EVENT_0];
WSAResetEvent(g_events[g_index-WSA_WAIT_EVENT_0]);
if(WSAGetOverlappedResult(pSI->s,&(pSI->o),&dwBytesTransferred,
FALSE,&dwFlags)==FALSE||dwBytesTransferred==0)
{
printf("Closingsocket%d\n",pSI->s);
if(closesocket(pSI->s)==SOCKET_ERROR)
{
printf("错误:
closesocket()failedwitherror%d\n",WSAGetLastError());
}
GlobalFree(pSI);
WSACloseEvent(g_events[g_index-WSA_WAIT_EVENT_0]);
//Cleanupg_socketsandg_eventsbyremovingthesocketeventhandle
//andsocketinformationstructureiftheyarenotattheendofthe
//arrays.
EnterCriticalSection(&g_cs);
if((g_index-WSA_WAIT_EVENT_0)+1!
=g_dwEventTotal)
for(i=g_index-WSA_WAIT_EVENT_0;i { g_events[i]=g_events[i+1]; g_sockets[i]=g_sockets[i+1]; } g_dwEventTotal--; LeaveCriticalSection(&g_cs); continue; } //已经有数据传递 if(pSI->nStatus==WSA_RECV) { memcpy(&pSI->buffRecv[pSI->dwBytesRecv],pSI->wsaBuf.buf,dwBytesTransferred); pSI->dwBytesRecv+=dwBytesTransferred; printf("接受: %s\n",pSI->buffRecv); if(pSI->buffRecv[pSI->dwBytesRecv-2]=='\r'//要保证最后是\r\n &&pSI->buffRecv[pSI->dwBytesRecv-1]=='\n' &&pSI->dwBytesRecv>2) { if(! g_bLoggedIn) { if(LoginIn(pSI)==LOGGED_IN) g_bLoggedIn=TRUE; } else { if(DealCommand(pSI)==FTP_QUIT) continue; } //缓冲区清除 memset(pSI->buffRecv,0,sizeof(pSI->buffRecv)); pSI->dwBytesRecv=0; } } else { pSI->dwBytesSend+=dwBytesTransferred; } //继续接收以后到来的数据 if(RecvReq(pSI)==-1) return-1; } return0; } //由于只是简单的出现一个登录信息,直接用send就可以了 intSendRes(LPSOCKET_INFpSI) { staticDWORDdwSendBytes=0; pSI->nStatus=WSA_SEND; memset(&(pSI->o),0,sizeof(WSAOVERLAPPED)); pSI->o.hEvent=g_events[g_index-WSA_WAIT_EVENT_0]; pSI->wsaBuf.buf=pSI->buffSend+pSI->dwBytesSend; pSI->wsaBuf.len=strlen(pSI->buffSend)-pSI->dwBytesSend; if(WSASend(pSI->s,&(pSI->wsaBuf),1,&dwSendBytes, 0,&(pSI->o),NULL)==SOCKET_ERROR) { if(WSAGetLastError()! =ERROR_IO_PENDING) { printf("WSASend()failedwitherror%d\n",WSAGetLastError()); return-1; } } return0; } //接受数据 intRecvReq(LPSOCKET_INFpSI) { staticDWORDdwRecvBytes=0; pSI->nStatus=WSA_RECV; DWORDdwFlags=0; memset(&(pSI->o),0,sizeof(WSAOVERLAPPED)); pSI->o.hEvent=g_events[g_index-WSA_WAIT_EVENT_0]; pSI->wsaBuf.len=DATA_BUFSIZE; if(WSARecv(pSI->s,&(pSI->wsaBuf),1,&dwRecvBytes, &dwFlags,&(pSI->o),NULL)==SOCKET_ERROR) { if(WSAGetLastError()! =ERROR_IO_PENDING) { printf("WSARecv()failedwitherror%d\n",WSAGetLastError()); return-1; } } return0; } //显示欢迎消息 BOOLWelcomeInfo(SOCKETs) { char*szWelcomeInfo="220欢迎您登录到MiniFtpServer...\r\n"; if(send(s,szWelcomeInfo,strlen(szWelcomeInfo),0)==SOCKET_ERROR) { printf("Ftpclienterror: %d\n",WSAGetLastError()); returnFALSE; } //刚进来,还没连接,故设置初始状态为false g_bLoggedIn=FALSE; returnTRUE; } //登录函数 intLoginIn(LPSOCKET_INFpSocketInfo) { constchar*szUserOK="331Usernameokay,needpassword.\r\n"; constchar*szLoggedIn="230Userloggedin,proceed.\r\n"; intnRetVal=0; staticcharszUser[MAX_NAME_LEN],szPwd[MAX_PWD_LEN]; LPSOCKET_INFpSI=pSocketInfo; //取得登录用户名 if(strstr(strupr(pSI->buffRecv),"USER")) { sprintf(szUser,"%s",pSI->buffRecv+strlen("USER")+1); strtok(szUser,"\r\n"); //响应信息 sprintf(pSI->buffSend,"%s",szUserOK); if(SendRes(pSI)==-1)return-1; returnUSER_OK; } if(strstr(strupr(pSI->buffRecv),"PASS")||strstr(pSI->buffRecv,"pass")) { sprintf(szPwd,"%s",pSI->buffRecv+strlen("PASS")+1); strtok(szPwd,"\r\n"); //判断用户名跟口令正确性 if(stricmp(szPwd,FTP_USER)||stricmp(szUser,FTP_PASS)) { sprintf(pSI->buffSend,"530User%s
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- FTPserver 部分 代码