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 " < "< 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 " < "< 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; } } } } }


发布评论