TFTP服务器代码文档格式.docx
《TFTP服务器代码文档格式.docx》由会员分享,可在线阅读,更多相关《TFTP服务器代码文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
---------------------
|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"
)
/*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))<
bind"
for(;
;
){
fromlen=sizeof(from);
recvfrom(sock[0],recvbuf,sizeof(recvbuf),0,(sockaddr*)&
from,&
fromlen);
if(recvbuf[0]==0&
&
recvbuf[1]<
3&
recvbuf[1]>
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))<
newaddr.sin_family=AF_INET;
newaddr.sin_port=0;
newaddr.sin_addr.s_addr=INADDR_ANY;
(newaddr.sin_zero),0,8);
if(bind(sock[i],(structsockaddr*)&
newaddr,sizeof(structsockaddr))<
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,&
}else{
len=makeerror(4,"
llegalTFTPoperation\0"
sendbuf,sizeof(sendbuf));
sendto(sock[0],sendbuf,len,0,(sockaddr*)&
from,sizeof(from));
}
voidshowsysinfo()
TFTPserverversion1.0\r\n"
intmakeack(unsignedshortnum,char*buffer,intsize)
intpos=0;
buffer[pos]=0;
pos++;
buffer[pos]=TFTP_ACK;
buffer[pos]=(char)(num>
>
8);
buffer[pos]=(char)num;
returnpos;
intmakedata(intnum,char*data,intdatasize,char*buffer,intbufsize)
buffer[pos]=TFTP_DATA;
memcpy(&
buffer[pos],data,datasize);
pos=pos+datasize;
intmakeerror(interrcode,char*errstring,char*buffer,intbufsize)
inti;
buffer[pos]=TFTP_ERROR;
buffer[pos]=(char)(errcode>
buffer[pos]=(char)errcode;
for(i=0;
buffer[pos]=errstring[i];
if(errstring[i]=='
voidgetfile(DATA*needdata)
intlen=0;
//fd_setfdr;
intretry=0;
//structtimevaltimeout={5,0};
intstat=0;
intlastdata=0;
longflen=0;
FILE*file;
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->
if((file=fopen(needdata->
filename,"
rb"
))!
=NULL){
fclose(file);
file%salreadyexist\n"
filename);
len=makeerror(6,"
filealreadyexist\0"
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->
w+b"
))==NULL){
tcreatefile\r\n"
len=makeack(lastdata,sendbuf,sizeof(sendbuf));
ret=sendto(sock[needdata->
//printf("
sendack0#to%s\n"
while(true){
/*FD_ZERO(&
fdr);
FD_SET(sock[needdata->
socknum],&
ret=select(sock[needdata->
fdr,NULL,NULL,NULL);
if(SOCKET_ERROR==ret){
socketerror\r\n"
}elseif(0==ret){
if(MAX_RETRY==retry){
Timeout\r\n"
retry++;
if(FD_ISSET(sock[needdata->
fdr)){
retry=0;
fromlen=sizeof(sockaddr);
ret=recvfrom(sock[needdata->
socknum],recvbuf,sizeof(recvbuf),0,(sockaddr*)&
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;
receiveddatablock%d#from%s\n"
lastdata,needdata->
sendack%d#to%s\n"
if(ret<
TFTP_NOTEND_DATALEN){
fwrite(&
recvbuf[4],1,ret-4,file);
flen=flen+ret-4;
total%dbytereceivedfrom%s\n"
flen,needdata->
logfile<
"
received"
<
needdata->
filename<
"
from"
remoteaddr<
\r\n"
endl;
recvbuf[4],1,512,file);
flen=flen+512;
%dbytereceived\r"
flen);
//}
voidputfile(DATA*needdata)
chardatabuf[1024]={0};
fd_setfdr;
structtimevaltimeout={5,0};
intstat=TFTP_WSTAT_NEXTACK;
intlastack=0;
intflen=0;
intblocknum=0;
size_trlen=0;
receivedRRQform%s\n"
file%snotfound\r\n"
len=makeerror(1,"
filenotfound\0"
rlen=fread(databuf,1,512,file);
if(rlen<
512&
feof(file)){
stat=TFTP_WSTAT_LASTACK;
}elseif(ferror(file)){
error:
readfile\r\n"
flen=flen+rlen;
blocknum++;
len=makedata(blocknum,databuf,rlen,sendbuf,sizeof(sendbuf));
senddatablock%d#to%s\n"
blocknum,needdata->
for(;
FD_ZERO(&
fdr,NULL,NULL,&
timeout);
socketerror\r\n"
timeout\r\n"
//