2024年2月20日发(作者:)

#define _VC

#include

#include

#include

#include

#include

#ifndef MAKEWORD

#define MAKEWORD(l,h) ((WORD)(((BYTE)(l))|(((WORD)(BYTE)(h))<<8)))

#endif

#define WSA_MAJOR_VERSION 1

#define WSA_MINOR_VERSION 1

#define WSA_VERSION MAKEWORD(WSA_MAJOR_VERSION, WSA_MINOR_VERSION)

/* read/write request packet format

2 bytes string 1 byte string 1 byte

------------------------------------------------

| Opcode | Filename | 0 | Mode | 0 |

------------------------------------------------

*/

#define TFTP_RRQ 1 /*Read request (RRQ)*/

#define TFTP_WRQ 2 /*Write request (WRQ) */

/* DATA packet format

2 bytes 2 bytes n bytes

----------------------------------

| Opcode | Block # | Data |

----------------------------------

*/

#define TFTP_DATA 3 /*Data (DATA)*/

/* ACK packet format

2 bytes 2 bytes

---------------------

| Opcode | Block # |

---------------------

*/

#define TFTP_ACK 4 /*Acknowledgment (ACK)*/

/*ERROR packet format

2 bytes 2 bytes string 1 byte

-----------------------------------------

| Opcode | ErrorCode | ErrMsg | 0 |

-----------------------------------------

*/

#define TFTP_ERROR 5 /*Error (ERROR)*/

#define TFTP_NETASCII 0

#define TFTP_OCTET 1

#define TFTP_WSTAT_FIRSTACKE 0

#define TFTP_WSTAT_NEXTACK 1

#define TFTP_WSTAT_LASTACK 2

#define MAX_RETRY 3

#define TFTP_NOTEND_DATALEN 512+2+2

#ifdef _VC

#pragma comment(lib,"")

#endif

/*typedef void (* CMDFUNC)(char [][256],int pcout);

typedef struct _cmdnum{

char *cmd;

int num;

int paramcount;

CMDFUNC callback;

}CMDNUM,*PCMDNUM;*/

typedef struct DATA{

int socknum;

char *filename;

unsigned short remoteport;

char *remoteaddr;

};

DATA passdata[6];

ofstream logfile("",ios::app);

int makeack(unsigned short num,char *buffer,int size);

void showsysinfo();

void getfile(DATA *needdata);

void putfile(DATA *needdata);

int makeerror(int errcode,char errstring[256],char *buffer,int bufsize);

SOCKET

sock[6]={INVALID_SOCKET,INVALID_SOCKET,INVALID_SOCKET,INVALID_SOCKET,INVALID_SOCKET,INVALID_SOCKET};

int filemode =TFTP_OCTET;

#define MYPORT 69

void main(int argc,char *argv[])

{

WSADATA stWSAData;

int ret=0;

sockaddr_in addr;

char recvbuf[1024]={0};

char sendbuf[1024]={0};

sockaddr_in from;

sockaddr_in newaddr;

int fromlen=0;

char filename[256];

int i,len;

DWORD ThreadID[6];

showsysinfo();

if(WSAStartup(WSA_VERSION,&stWSAData)!=0){

printf("can't start socket rn");

exit(0);

}

if ((sock[0]=socket(AF_INET,SOCK_DGRAM,0))<0){

perror("socket");

exit(1);

}

_family=AF_INET;

_port=htons(MYPORT);

_addr.s_addr=INADDR_ANY;

memset(&(_zero),0,8);

if (bind(sock[0],(struct sockaddr *)&addr,sizeof(struct sockaddr))<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);

}

_family=AF_INET;

_port=0;

_addr.s_addr=INADDR_ANY;

memset(&(_zero),0,8);

if (bind(sock[i],(struct sockaddr *)&newaddr,sizeof(struct sockaddr))<0){

perror("bind");

exit(1);

}

break;

}

}

passdata[i].filename=filename;

passdata[i].remoteport=ntohs(_port);

passdata[i].remoteaddr=inet_ntoa(_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,"llegal TFTP operation0",sendbuf,sizeof(sendbuf));

sendto(sock[0],sendbuf,len,0,(sockaddr *)&from,sizeof(from));

}

}

}

void showsysinfo()

{

printf("TFTP server version 1.0rn");

}

int makeack(unsigned short num,char *buffer,int size)

{

int pos=0;

buffer[pos]=0;

pos++;

buffer[pos]=TFTP_ACK;

pos++;

buffer[pos]=(char)(num>>8);

pos++;

buffer[pos]=(char)num;

pos++;

return pos;

}

int makedata(int num,char *data,int datasize,char *buffer,int bufsize)

{

int pos=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;

return pos;

}

int makeerror(int errcode,char *errstring,char *buffer,int bufsize)

{

int pos=0;

int i;

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;

}

return pos;

}

void getfile(DATA *needdata)

{

char sendbuf[1024]={0};

char recvbuf[1024]={0};

sockaddr_in addr;

sockaddr_in from;

int fromlen=0;

int ret=0;

int len=0;

// fd_set fdr;

int retry=0;

// struct timeval timeout={5,0};

int stat=0;

int lastdata=0;

long flen=0;

FILE *file;

_family=AF_INET;

_family=AF_INET;

_port=htons(needdata->remoteport);

_addr.s_addr=inet_addr(needdata->remoteaddr);

// printf("received WRQ form %sn",needdata->remoteaddr);

if((file=fopen(needdata->filename,"rb"))!=NULL){

fclose(file);

printf("file %s already existn",needdata->filename);

len=makeerror(6,"file already exist0",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't create file rn");

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("send ack 0# to %sn",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("socket error rn");

fclose(file);

return;

} else if (0==ret){

if (MAX_RETRY==retry){

printf("Time outrn");

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){

_port=_port;

stat=1;

}

if(TFTP_DATA==recvbuf[1]){

lastdata=((recvbuf[2]+256)%256)*256+(recvbuf[3]+256)%256;

// printf("received data block %d#

from %sn",lastdata,needdata->remoteaddr);

len=makeack(lastdata,sendbuf,sizeof(sendbuf));

sendto(sock[needdata->socknum],sendbuf,len,0,(sockaddr

*)&addr,sizeof(addr));

// printf("send ack %d# to %sn",lastdata,needdata->remoteaddr);

if(ret

fwrite(&recvbuf[4],1,ret-4,file);

flen=flen+ret-4;

fclose(file);

printf("total %d byte received

from %sn",flen,needdata->remoteaddr);

logfile << "received " <filename<<" from

"<remoteaddr<<"rn"<

closesocket(sock[needdata->socknum]);

sock[needdata->socknum]=INVALID_SOCKET;

return;

} else {

fwrite(&recvbuf[4],1,512,file);

flen=flen+512;

// printf("%d byte receivedr",flen);

}

}

// }

// }

}

}

void putfile(DATA *needdata)

{

char sendbuf[1024]={0};

char recvbuf[1024]={0};

char databuf[1024]={0};

sockaddr_in addr;

sockaddr_in from;

int fromlen=0;

int ret=0;

int len=0;

fd_set fdr;

int retry=0;

struct timeval timeout={5,0};

int stat=TFTP_WSTAT_NEXTACK;

int lastack=0;

FILE *file;

int flen=0;

int blocknum=0;

size_t rlen=0;

_family=AF_INET;

_family=AF_INET;

_port=htons(needdata->remoteport);

_addr.s_addr=inet_addr(needdata->remoteaddr);

// printf("received RRQ form %sn",needdata->remoteaddr);

if((file=fopen(needdata->filename,"rb"))==NULL){

printf("file %s not foundrn",needdata->filename);

len=makeerror(1,"file not found0",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;

} else if (ferror(file)){

printf("error:read filern");

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("send data block %d# to %sn",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("socket errorrn");

fclose(file);

return;

} else if (0==ret){

if (MAX_RETRY==retry){

printf("time outrn");

fclose(file);

closesocket(sock[needdata->socknum]);

sock[needdata->socknum]=INVALID_SOCKET;

return;

}

sendto(sock[needdata->socknum],sendbuf,len,0,(sockaddr *)&addr,sizeof(addr));

// printf("send data block %d# to %sn",blocknum,needdata->remoteaddr);

retry++;

} else {

retry=0;

fromlen=sizeof(sockaddr);

ret=recvfrom(sock[needdata->socknum],recvbuf,sizeof(recvbuf),0,(sockaddr

*)&from,&fromlen);

if(TFTP_ACK==recvbuf[1]){

lastack=((recvbuf[2]+256)%256)*256+(recvbuf[3]+256)%256;

// printf("received ack %d# from %sn",lastack,needdata->remoteaddr);

switch(stat){

case TFTP_WSTAT_NEXTACK:

if (lastack==blocknum){

// printf("%d byte sendr",flen);

rlen=fread(databuf,1,512,file);

flen=flen+rlen;

if(rlen<512 && feof(file)){

stat=TFTP_WSTAT_LASTACK;

} else if (ferror(file)) {

printf("error:read file");

fclose(file);

return;

}

if (blocknum<65535) {

blocknum++;

} else blocknum=1;

len=makedata(blocknum,databuf,rlen,sendbuf,sizeof(sendbuf));

sendto(sock[needdata->socknum],sendbuf,len,0,(sockaddr

*)&addr,sizeof(addr));

// printf("send data block %d#

to %sn",blocknum,needdata->remoteaddr);

} else {

fclose(file);

printf("error ack numbern");

closesocket(sock[needdata->socknum]);

sock[needdata->socknum]=INVALID_SOCKET;

return;

}

break;

case TFTP_WSTAT_LASTACK:

if (lastack==blocknum){

fclose(file);

printf("totle %d byte send to %sn",flen,needdata->remoteaddr);

logfile << "send " <filename<<" to

"<remoteaddr<<"rn"<

closesocket(sock[needdata->socknum]);

sock[needdata->socknum]=INVALID_SOCKET;

return;

} else {

fclose(file);

printf("error ack number");

closesocket(sock[needdata->socknum]);

sock[needdata->socknum]=INVALID_SOCKET;

return;

}

break;

}

}

}

}

}