📄 excute.cpp
字号:
timeFormat,inet_ntoa(RcvAddr.sin_addr),RcvPort,fileandmode);
::SendMessage(tftpHwnd,WM_DATADISPLAY,0,(LPARAM)strDisplay);
fwrite(strDisplay,1,strlen(strDisplay),stream);
b=0;
AckBuf ABuf;
DataBuf DBuf;
ABuf.pcode = htons(ACK);
DBuf.pcode = htons(DAT);
//测试打开请求下载文件
if((pFile = fopen(fileandmode,"r"))!=NULL)
{
//请求文件存在,拒绝覆盖可以保护用户文件覆盖掉 server 上的文件
SendErrors(6);
timeNow = CTime::GetCurrentTime();
timeFormat=timeNow.Format("%H:%M:%S");
sprintf(strDisplay,"%s : 服务器存在同名文件 : %s,中止[%s:%d]!\n",
timeFormat,fileandmode,inet_ntoa(RcvAddr.sin_addr),RcvPort);
::SendMessage(tftpHwnd,WM_DATADISPLAY,0,(LPARAM)strDisplay);
fwrite(strDisplay,1,strlen(strDisplay),stream);
fclose(pFile);
return;
}
CFile *pCFile1;
//请求文件不存在,为 Client 创建文件
pCFile1 = new CFile((LPCTSTR)fileandmode, CFile::modeCreate|CFile::modeWrite);
char RcvBuf[1024];
fd_set SockSet;
while(1)
{
memset(DBuf.buf,0,sizeof(DBuf.buf));
ABuf.block = htons(b);
timeNow=CTime::GetCurrentTime();
timeFormat=timeNow.Format("%H:%M:%S");
sprintf(strDisplay,"%s : 回送 [%s:%d] 第 %d 号 ACK\n",
timeFormat,inet_ntoa(RcvAddr.sin_addr),RcvPort,b);
::SendMessage(tftpHwnd,WM_DATADISPLAY,0,(LPARAM)strDisplay);
fwrite(strDisplay,1,strlen(strDisplay),stream);
while(1)
{
//发送ACK
memset(DBuf.buf,0,sizeof(DBuf.buf));
sendto(SrvSocket,(char*)&ABuf,
sizeof(ABuf),0,(SOCKADDR*)&RcvAddr,len);
FD_ZERO(&SockSet);
FD_SET(SrvSocket,&SockSet);
if(select(SrvSocket,&SockSet,NULL,NULL,&TVal))
{
nBytesRcv = recvfrom(SrvSocket,RcvBuf,
sizeof(RcvBuf),0,(SOCKADDR *)&RcvAddr,&len);
nBytesRcv -= 4;
timeNow=CTime::GetCurrentTime();
timeFormat=timeNow.Format("%H:%M:%S");
if(u_short(ntohs(ABuf.block) + 1) != u_short(ntohs(((DataBuf*)RcvBuf)->block)) ||
ntohs(((DataBuf*)RcvBuf)->pcode) != DAT)
{
//DATA 序列号出错,或不是 DATA 包处理
if(((ErrorBuf*)RcvBuf)->pcode == ntohs(ERR))
{
SetErrMsg(ntohs(((ErrorBuf*)RcvBuf)->ErrorCode));
return;
}
if(timeout == 5)
{
//重复五次错误 DATA, 中止服务
sprintf(strDisplay,"%s : 中止 [%s:%d], 出错重发第 %d 号ACK %d 次\n",
timeFormat,inet_ntoa(RcvAddr.sin_addr),RcvPort,b,timeout);
::SendMessage(tftpHwnd,WM_DATADISPLAY,0,(LPARAM)strDisplay);
fwrite(strDisplay,1,strlen(strDisplay),stream);
timeout = 0;
delete pCFile1;
return;
}
timeNow=CTime::GetCurrentTime();
timeFormat=timeNow.Format("%H:%M:%S");
sprintf(strDisplay,"%s : 收到 [%s:%d] 第 %d 号 DATA, 重发第 %d 次 ACK\n",timeFormat,
inet_ntoa(RcvAddr.sin_addr),RcvPort,ntohs(((DataBuf*)RcvBuf)->block),timeout);
::SendMessage(tftpHwnd,WM_DATADISPLAY,0,(LPARAM)strDisplay);
fwrite(strDisplay,1,strlen(strDisplay),stream);
timeout++;
continue;
}
else//right datagram
{
sprintf(strDisplay,"%s : 收到 [%s:%d] 第 %d 号 DATA,%d Bytes\n",timeFormat,
inet_ntoa(RcvAddr.sin_addr),RcvPort,ntohs(((DataBuf*)RcvBuf)->block),nBytesRcv);
::SendMessage(tftpHwnd,WM_DATADISPLAY,0,(LPARAM)strDisplay);
fwrite(strDisplay,1,strlen(strDisplay),stream);
TotalBytes += nBytesRcv;
pCFile1->Write(((DataBuf*)RcvBuf)->buf,nBytesRcv);
b = ntohs(((DataBuf*)RcvBuf)->block);
if(nBytesRcv < 512)
{
//最后一个包,传送完成
ABuf.block = htons(b);
sendto(SrvSocket,(char*)&ABuf,
sizeof(ABuf),0,(SOCKADDR*)&RcvAddr,len);
timeNow=CTime::GetCurrentTime();
timeFormat=timeNow.Format("%H:%M:%S");
sprintf(strDisplay,"%s : 回送 [%s:%d] 第 %d 号 ACK",
timeFormat,inet_ntoa(RcvAddr.sin_addr),RcvPort,b);
::SendMessage(tftpHwnd,WM_DATADISPLAY,0,(LPARAM)strDisplay);
fwrite(strDisplay,1,strlen(strDisplay),stream);
delete pCFile1;
timeNow=CTime::GetCurrentTime();
timeFormat=timeNow.Format("%H:%M:%S");
TotalTime -= timeNow.GetHour();
if(TotalTime <= 0)
TotalTime = TotalTime * 60;//传文件时间不得超过24小时,
else //否则检查不出正确耗时
TotalTime = 24 * 60;
TotalTime += timeNow.GetMinute() - StartTime.GetMinute();
TotalTime = TotalTime * 60;
TotalTime += timeNow.GetSecond() - StartTime.GetSecond();
if(TotalTime == 0)
TotalTime = 1;
sprintf(strDisplay,"%s : [%s:%d]%s上传完毕: %d Bytes int %d seconds, %d Bytes/s.\n",
timeFormat,inet_ntoa(RcvAddr.sin_addr),RcvPort,fileandmode,TotalBytes,TotalTime,int(TotalBytes/TotalTime));
::SendMessage(tftpHwnd,WM_DATADISPLAY,0,(LPARAM)strDisplay);
fwrite(strDisplay,1,strlen(strDisplay),stream);
delete pCFile1;
fclose(stream);
return;
}
timeout = 1;
break;
}
}
else
{
if(timeout == 5)
{
//重复五次 select 超时,中止服务
delete pCFile1;
timeout = 0;
sprintf(strDisplay,"%s : 接收 [%s:%d] 第 %d 号 DATA 超时,中止服务!\n",timeFormat,
inet_ntoa(RcvAddr.sin_addr),RcvPort,ntohs(((DataBuf*)RcvBuf)->block)+1);
::SendMessage(tftpHwnd,WM_DATADISPLAY,0,(LPARAM)strDisplay);
fwrite(strDisplay,1,strlen(strDisplay),stream);
return;
}
timeout++;
}
}//if select
}//while(1)
break;
default:
SendErrors(0);
fclose(stream);
return;
}
}
void Cexcute::SendErrors(u_short m_ErrorNum)
{
ErrorBuf EBuf;
memset(EBuf.ErrMsg,0,100);
EBuf.pcode = htons(ERR);
switch(m_ErrorNum)
{
case 0:
strcpy(EBuf.ErrMsg,"Not defined, see error message (if any).\n");
EBuf.ErrorCode = htons(0);
break;
case 1:
strcpy(EBuf.ErrMsg,"File not found.\n");
EBuf.ErrorCode = htons(1);
break;
case 2:
strcpy(EBuf.ErrMsg,"Access violation.\n");
EBuf.ErrorCode = htons(2);
break;
case 3:
strcpy(EBuf.ErrMsg,"Disk full or allocation exceeded.\n");
EBuf.ErrorCode = htons(3);
break;
case 4:
strcpy(EBuf.ErrMsg,"Illegal TFTP operation.\n");
EBuf.ErrorCode = htons(4);
break;
case 5:
strcpy(EBuf.ErrMsg,"Unknown transfer ID.\n");
EBuf.ErrorCode = htons(5);
break;
case 6:
strcpy(EBuf.ErrMsg,"File already exists.\n");
EBuf.ErrorCode = htons(6);
break;
case 7:
strcpy(EBuf.ErrMsg,"No such user.\n");
EBuf.ErrorCode = htons(7);
break;
}
sendto(SrvSocket,(char *)&EBuf,sizeof(ErrorBuf),0,(SOCKADDR*)&RcvAddr,len);
}
//线程结束时,删除存在节点的记录
void Cexcute::DeleteRQ(SOCKADDR_IN RcvAddr)
{
ExistRQ * tmp, *bftmp;
bftmp = RQHead;
tmp = bftmp;
while(tmp != NULL)
{
if(RcvAddr.sin_port == tmp->m_Port &&
RcvAddr.sin_addr.S_un.S_addr == tmp->m_Addr.S_un.S_addr)
{
if(bftmp == RQHead)
RQHead = tmp->next;
else
bftmp->next = tmp->next;
delete tmp;
}
else
{
bftmp = tmp;
tmp=tmp->next;
}
}
}
//显示错误信息函数
void Cexcute::SetErrMsg(u_short ErrNum)
{
switch(ErrNum)
{
case 0:
sprintf(strDisplay,"Not defined, see error message (if any).\n");
break;
case 1:
sprintf(strDisplay,"Server Error: File not found.\n");
break;
case 2:
sprintf(strDisplay,"Access violation.\n");
break;
case 3:
sprintf(strDisplay,"Disk full or allocation exceeded.\n");
break;
case 4:
sprintf(strDisplay,"Illegal TFTP operation mode.\n");
break;
case 5:
sprintf(strDisplay,"Unknown transfer ID.\n");
break;
case 6:
sprintf(strDisplay,"Server Error: File already exists.\n");
break;
case 7:
sprintf(strDisplay,"No such user.\n");
break;
}
::SendMessage(tftpHwnd,WM_DATADISPLAY,0,(LPARAM)strDisplay);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -