TFTP服务器代码.docx
- 文档编号:8020159
- 上传时间:2023-01-28
- 格式:DOCX
- 页数:15
- 大小:16.98KB
TFTP服务器代码.docx
《TFTP服务器代码.docx》由会员分享,可在线阅读,更多相关《TFTP服务器代码.docx(15页珍藏版)》请在冰豆网上搜索。
TFTP服务器代码
#define_VC
#include
#include
#include
#include
#include
#ifndefMAKEWORD
#defineMAKEWORD(l,h)((WORD)(((BYTE)(l))|(((WORD)(BYTE)(h))<<8)))
#endif
#defineWSA_MAJOR_VERSION1
#defineWSA_MINOR_VERSION1
#defineWSA_VERSIONMAKEWORD(WSA_MAJOR_VERSION,WSA_MINOR_VERSION)
/*read/writerequestpacketformat
2bytesstring1bytestring1byte
------------------------------------------------
|Opcode|Filename|0|Mode|0|
------------------------------------------------
*/
#defineTFTP_RRQ1/*Readrequest(RRQ)*/
#defineTFTP_WRQ2/*Writerequest(WRQ)*/
/*DATApacketformat
2bytes2bytesnbytes
----------------------------------
|Opcode|Block#|Data|
----------------------------------
*/
#defineTFTP_DATA3/*Data(DATA)*/
/*ACKpacketformat
2bytes2bytes
---------------------
|Opcode|Block#|
---------------------
*/
#defineTFTP_ACK4/*Acknowledgment(ACK)*/
/*ERRORpacketformat
2bytes2bytesstring1byte
-----------------------------------------
|Opcode|ErrorCode|ErrMsg|0|
-----------------------------------------
*/
#defineTFTP_ERROR5/*Error(ERROR)*/
#defineTFTP_NETASCII0
#defineTFTP_OCTET1
#defineTFTP_WSTAT_FIRSTACKE0
#defineTFTP_WSTAT_NEXTACK1
#defineTFTP_WSTAT_LASTACK2
#defineMAX_RETRY3
#defineTFTP_NOTEND_DATALEN512+2+2
#ifdef_VC
#pragmacomment(lib,"Wsock32.lib")
#endif
/*typedefvoid(*CMDFUNC)(char[][256],intpcout);
typedefstruct_cmdnum{
char*cmd;
intnum;
intparamcount;
CMDFUNCcallback;
}CMDNUM,*PCMDNUM;*/
typedefstructDATA{
intsocknum;
char*filename;
unsignedshortremoteport;
char*remoteaddr;
};
DATApassdata[6];
ofstreamlogfile("log.txt",ios:
:
app);
intmakeack(unsignedshortnum,char*buffer,intsize);
voidshowsysinfo();
voidgetfile(DATA*needdata);
voidputfile(DATA*needdata);
intmakeerror(interrcode,charerrstring[256],char*buffer,intbufsize);
SOCKETsock[6]={INVALID_SOCKET,INVALID_SOCKET,INVALID_SOCKET,INVALID_SOCKET,INVALID_SOCKET,INVALID_SOCKET};
intfilemode=TFTP_OCTET;
#defineMYPORT69
voidmain(intargc,char*argv[])
{
WSADATAstWSAData;
intret=0;
sockaddr_inaddr;
charrecvbuf[1024]={0};
charsendbuf[1024]={0};
sockaddr_infrom;
sockaddr_innewaddr;
intfromlen=0;
charfilename[256];
inti,len;
DWORDThreadID[6];
showsysinfo();
if(WSAStartup(WSA_VERSION,&stWSAData)!
=0){
printf("can'tstartsocket\r\n");
exit(0);
}
if((sock[0]=socket(AF_INET,SOCK_DGRAM,0))<0){
perror("socket");
exit
(1);
}
addr.sin_family=AF_INET;
addr.sin_port=htons(MYPORT);
addr.sin_addr.s_addr=INADDR_ANY;
memset(&(addr.sin_zero),0,8);
if(bind(sock[0],(structsockaddr*)&addr,sizeof(structsockaddr))<0){
perror("bind");
exit
(1);
}
for(;;){
fromlen=sizeof(from);
recvfrom(sock[0],recvbuf,sizeof(recvbuf),0,(sockaddr*)&from,&fromlen);
if(recvbuf[0]==0&&recvbuf[1]<3&&recvbuf[1]>0){
for(i=0;;i++){
filename[i]=recvbuf[i+2];
if(filename[i]=='\0')break;
}
for(i=1;i<=5;i++){
if(sock[i]==INVALID_SOCKET){
passdata[i].socknum=i;
if((sock[i]=socket(AF_INET,SOCK_DGRAM,0))<0){
perror("socket");
exit
(1);
}
newaddr.sin_family=AF_INET;
newaddr.sin_port=0;
newaddr.sin_addr.s_addr=INADDR_ANY;
memset(&(newaddr.sin_zero),0,8);
if(bind(sock[i],(structsockaddr*)&newaddr,sizeof(structsockaddr))<0){
perror("bind");
exit
(1);
}
break;
}
}
passdata[i].filename=filename;
passdata[i].remoteport=ntohs(from.sin_port);
passdata[i].remoteaddr=inet_ntoa(from.sin_addr);
if(recvbuf[1]==TFTP_WRQ){
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)getfile,&passdata[i],0,&ThreadID[i]);
}
if(recvbuf[1]==TFTP_RRQ){
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)putfile,&passdata[i],0,&ThreadID[i]);
}
}else{
len=makeerror(4,"llegalTFTPoperation\0",sendbuf,sizeof(sendbuf));
sendto(sock[0],sendbuf,len,0,(sockaddr*)&from,sizeof(from));
}
}
}
voidshowsysinfo()
{
printf("TFTPserverversion1.0\r\n");
}
intmakeack(unsignedshortnum,char*buffer,intsize)
{
intpos=0;
buffer[pos]=0;
pos++;
buffer[pos]=TFTP_ACK;
pos++;
buffer[pos]=(char)(num>>8);
pos++;
buffer[pos]=(char)num;
pos++;
returnpos;
}
intmakedata(intnum,char*data,intdatasize,char*buffer,intbufsize)
{
intpos=0;
buffer[pos]=0;
pos++;
buffer[pos]=TFTP_DATA;
pos++;
buffer[pos]=(char)(num>>8);
pos++;
buffer[pos]=(char)num;
pos++;
memcpy(&buffer[pos],data,datasize);
pos=pos+datasize;
returnpos;
}
intmakeerror(interrcode,char*errstring,char*buffer,intbufsize)
{
intpos=0;
inti;
buffer[pos]=0;
pos++;
buffer[pos]=TFTP_ERROR;
pos++;
buffer[pos]=(char)(errcode>>8);
pos++;
buffer[pos]=(char)errcode;
pos++;
for(i=0;;i++){
buffer[pos]=errstring[i];
pos++;
if(errstring[i]=='\0')break;
}
returnpos;
}
voidgetfile(DATA*needdata)
{
charsendbuf[1024]={0};
charrecvbuf[1024]={0};
sockaddr_inaddr;
sockaddr_infrom;
intfromlen=0;
intret=0;
intlen=0;
//fd_setfdr;
intretry=0;
//structtimevaltimeout={5,0};
intstat=0;
intlastdata=0;
longflen=0;
FILE*file;
addr.sin_family=AF_INET;
from.sin_family=AF_INET;
addr.sin_port=htons(needdata->remoteport);
addr.sin_addr.s_addr=inet_addr(needdata->remoteaddr);
//printf("receivedWRQform%s\n",needdata->remoteaddr);
if((file=fopen(needdata->filename,"rb"))!
=NULL){
fclose(file);
printf("file%salreadyexist\n",needdata->filename);
len=makeerror(6,"filealreadyexist\0",sendbuf,sizeof(sendbuf));
sendto(sock[needdata->socknum],sendbuf,len,0,(sockaddr*)&addr,sizeof(addr));
closesocket(sock[needdata->socknum]);
sock[needdata->socknum]=INVALID_SOCKET;
return;
}
if((file=fopen(needdata->filename,"w+b"))==NULL){
printf("can'tcreatefile\r\n");
closesocket(sock[needdata->socknum]);
sock[needdata->socknum]=INVALID_SOCKET;
return;
}
len=makeack(lastdata,sendbuf,sizeof(sendbuf));
ret=sendto(sock[needdata->socknum],sendbuf,len,0,(sockaddr*)&addr,sizeof(addr));
//printf("sendack0#to%s\n",needdata->remoteaddr);
while(true){
/*FD_ZERO(&fdr);
FD_SET(sock[needdata->socknum],&fdr);
ret=select(sock[needdata->socknum],&fdr,NULL,NULL,NULL);
if(SOCKET_ERROR==ret){
printf("socketerror\r\n");
fclose(file);
return;
}elseif(0==ret){
if(MAX_RETRY==retry){
printf("Timeout\r\n");
fclose(file);
return;
}
sendto(sock[needdata->socknum],sendbuf,len,0,(sockaddr*)&addr,sizeof(addr));
retry++;
}else{
if(FD_ISSET(sock[needdata->socknum],&fdr)){
retry=0;*/
fromlen=sizeof(sockaddr);
ret=recvfrom(sock[needdata->socknum],recvbuf,sizeof(recvbuf),0,(sockaddr*)&from,&fromlen);
if(0==stat){
addr.sin_port=from.sin_port;
stat=1;
}
if(TFTP_DATA==recvbuf[1]){
lastdata=((recvbuf[2]+256)%256)*256+(recvbuf[3]+256)%256;
//printf("receiveddatablock%d#from%s\n",lastdata,needdata->remoteaddr);
len=makeack(lastdata,sendbuf,sizeof(sendbuf));
sendto(sock[needdata->socknum],sendbuf,len,0,(sockaddr*)&addr,sizeof(addr));
//printf("sendack%d#to%s\n",lastdata,needdata->remoteaddr);
if(ret fwrite(&recvbuf[4],1,ret-4,file); flen=flen+ret-4; fclose(file); printf("total%dbytereceivedfrom%s\n",flen,needdata->remoteaddr); logfile<<"received"< closesocket(sock[needdata->socknum]); sock[needdata->socknum]=INVALID_SOCKET; return; }else{ fwrite(&recvbuf[4],1,512,file); flen=flen+512; //printf("%dbytereceived\r",flen); } } //} //} } } voidputfile(DATA*needdata) { charsendbuf[1024]={0}; charrecvbuf[1024]={0}; chardatabuf[1024]={0}; sockaddr_inaddr; sockaddr_infrom; intfromlen=0; intret=0; intlen=0; fd_setfdr; intretry=0; structtimevaltimeout={5,0}; intstat=TFTP_WSTAT_NEXTACK; intlastack=0; FILE*file; intflen=0; intblocknum=0; size_trlen=0; addr.sin_family=AF_INET; from.sin_family=AF_INET; addr.sin_port=htons(needdata->remoteport); addr.sin_addr.s_addr=inet_addr(needdata->remoteaddr); //printf("receivedRRQform%s\n",needdata->remoteaddr); if((file=fopen(needdata->filename,"rb"))==NULL){ printf("file%snotfound\r\n",needdata->filename); len=makeerror(1,"filenotfound\0",sendbuf,sizeof(sendbuf)); sendto(sock[needdata->socknum],sendbuf,len,0,(sockaddr*)&addr,sizeof(addr)); closesocket(sock[needdata->socknum]); sock[needdata->socknum]=INVALID_SOCKET; return; } rlen=fread(databuf,1,512,file); if(rlen<512&&feof(file)){ stat=TFTP_WSTAT_LASTACK; }elseif(ferror(file)){ printf("error: readfile\r\n"); fclose(file); return; } flen=flen+rlen; blocknum++; len=makedata(blocknum,databuf,rlen,sendbuf,sizeof(sendbuf)); sendto(sock[needdata->socknum],sendbuf,len,0,(sockaddr*)&addr,sizeof(addr)); //printf("senddatablock%d#to%s\n",blocknum,needdata->remoteaddr); for(;;){ FD_ZERO(&fdr); FD_SET(sock[needdata->socknum],&fdr); ret=select(sock[needdata->socknum],&fdr,NULL,NULL,&timeout); if(SOCKET_ERROR==ret){ printf("socketerror\r\n"); fclose(file); return; }elseif(0==ret){ if(MAX_RETRY==retry){ printf("timeout\r\n"); fclose(file); closesocket(sock[needdata->socknum]); sock[needdata->socknum]=INVALID_SOCKET; return; } sendto(sock[needdata->socknum],sendbuf,len,0,(sockaddr*)&addr,sizeof(addr)); //
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- TFTP 服务器 代码