📄 tftpclient.c.txt
字号:
#include "tftpclient.h"
struct CONTEXT Context;
int main(int argc, char* argv[])
{
int sock;
struct sockaddr_in ServAddr;
struct sockaddr_in RemoteAddr;
// struct in_addr *clientaddr;
unsigned int RemoteAddrLen;
unsigned short *opcode;
int ret=0;
unsigned char msg[600], sendmsg[600];
int msgsize, sendsize;
struct RRQ *rrqpacket;
char filename[80];
FILE *fp;
if(argc != 4)
{
printf("\nUsage: %s ip_addr ip_port [r|w]", argv[0]);
exit(0);
}
if((sock=socket(PF_INET, SOCK_DGRAM, 0))<0)
{
printf("\n Error : socket() failed");
exit(-1);
}
memset(&ServAddr, 0, sizeof(ServAddr));
ServAddr.sin_family = AF_INET;
ServAddr.sin_addr.s_addr = inet_addr(argv[1]);
ServAddr.sin_port = htons(atoi(argv[2]));
if(argv[3][0] == 'r')
{
printf("\n Input the file name: ");
scanf("%s", filename);
rrqpacket = (struct RRQ *)sendmsg;
rrqpacket->OpCode = htons(RRQ_OPCODE);
strcpy(rrqpacket->FileName, filename);
strcpy(rrqpacket->Mode, BIN);
if((fp = fopen(filename, "w+b"))==NULL)
{
printf("\n Error : Cannot open for write");
exit(-1);
}
if( (sendsize = sendto(sock, sendmsg, sizeof(struct RRQ), 0,
(struct sockaddr*)&ServAddr, sizeof(ServAddr))) < 0 )
{
printf("\n Error : sendto() failed !!");
exit(-1);
}
printf("\n Send RRQ[%d]\n", sendsize);
memset(&Context, 0, sizeof(struct CONTEXT));
Context.State = RECV_DATA_STATE;
Context.RecvNumber = 1;
strcpy(Context.FileName, filename);
Context.fp=fp;
}
else if(argv[3][0] == 'w')
{
printf("\n Sorry .. Not implemented yet .");
exit(0);
}
else
{
printf("\n Unknown operation %s\n", argv[3]);
exit(0);
}
for(;;)
{
RemoteAddrLen = sizeof(RemoteAddr);
memset(msg, 0, sizeof(msg));
if( (msgsize = recvfrom(sock, msg, 600, 0, (struct sockaddr*)&RemoteAddr,
&RemoteAddrLen) ) < 0 )
{
printf("\n Error : recvfrom() failed !!\n");
exit(-1);
}
opcode = (unsigned short*)msg;
switch(ntohs(*opcode))
{
case DATA_OPCODE :
printf("\n Recv DATA msg[%d]\n", msgsize);
ret = process_DATA(sock, msg, msgsize, &RemoteAddr, RemoteAddrLen);
break;
case ACK_OPCODE :
ret = process_ACK(sock, msg, msgsize, &RemoteAddr, RemoteAddrLen);
break;
case ERROR_OPCODE :
printf("\n Recv ERROR msg[%d]\n", msgsize);
ret = process_ERROR(sock, msg, msgsize, &RemoteAddr, RemoteAddrLen);
break;
default :
printf("\n ERROR : Receive Unknown OpCode[%u] Packet !! -> Ignore\n ",
ntohs(*opcode));
ret=-1;
}
if(ret <= 0)
{
close(sock);
return 0;
}
}
return 0;
}
int process_DATA(int socket, char *msg, int recvsize,
struct sockaddr_in *remoteaddr, int remoteaddrsize)
{
FILE *fp;
struct DATA *datapacket;
struct ACK *ackpacket;
char sendmsg[600];
int writesize;
int sendsize;
if( recvsize < sizeof(struct DATA))
{
printf("\n Error : Bad DATA size: %d ", recvsize);
send_error(socket, remoteaddr, remoteaddrsize, 0, "Bad Packet Size");
return -1;
}
if( Context.State != RECV_DATA_STATE )
{
printf("\n Error : DATA but Bad state: %d ", Context.State);
send_error(socket, remoteaddr, remoteaddrsize, 0, "recv DATA but Bad state");
return -1;
}
datapacket = (struct DATA *)msg;
if( ntohs(datapacket->BlockNumber) != Context.RecvNumber)
{
printf("\n Error : DATA but error blocknumber %d Context.recvnumber %d",
ntohs(datapacket->BlockNumber), Context.RecvNumber);
send_error(socket, remoteaddr, remoteaddrsize, 0, "DATA but error blocknumber");
return 1;
}
writesize = recvsize-sizeof(struct DATA)+1;
printf("\n Write File [%d ~ %d] bytes", Context.CurrentByteSize,
Context.CurrentByteSize+writesize-1);
fwrite(datapacket->Data, 1, writesize, Context.fp);
ackpacket=(struct ACK *)sendmsg;
ackpacket->OpCode = htons(ACK_OPCODE);
ackpacket->BlockNumber= htons(Context.RecvNumber);
Context.RecvNumber++;
Context.CurrentByteSize += writesize;
if(writesize < 512)
{
printf("\n Receive All data ..\n");
fclose(Context.fp);
sendsize= sendto(socket, ackpacket, sizeof(struct ACK), 0,
(struct sockaddr*)remoteaddr, remoteaddrsize);
printf("\n Send LAST ACK[%d] Blocknum[%u] \n", sendsize, ntohs(ackpacket->BlockNumber));
return 0; // end of processing ..
}
sendsize=sendto(socket, ackpacket, sizeof(struct ACK), 0, (struct sockaddr*)remoteaddr,
remoteaddrsize);
printf("\n Send ACK[%d] Blocknum[%u] \n", sendsize, ntohs(ackpacket->BlockNumber));
return 1; // further processing required
}
int process_ACK(int socket, char *msg, int recvsize,
struct sockaddr_in *remoteaddr, int remoteaddrsize)
{
printf("\n Not Implemented yet.. ");
return 1;
}
int process_ERROR(int socket, char *msg, int recvsize,
struct sockaddr_in *remoteaddr, int remoteaddrsize)
{
struct ERROR *errorpacket;
if( recvsize < sizeof(struct ERROR))
{
printf("\n Error Packet : Bad ERROR size: %d ", recvsize);
return -1;
}
errorpacket = (struct ERROR *)msg;
printf("\n ERROR packet recv ErrorNumber: %u ErrorMsg : %s",
ntohs(errorpacket->OpCode), errorpacket->ErrorData);
return -1;
}
int send_error(int socket, struct sockaddr_in *remoteaddr, int remoteaddrsize,
unsigned short errorcode, char *errormsg)
{
char sendmsg[128];
struct ERROR *errorpacket;
errorpacket = (struct ERROR *)sendmsg;
errorpacket->OpCode = htons(ERROR_OPCODE);
errorpacket->ErrorNumber = htons(errorcode); // file not found ..
strcpy(errorpacket->ErrorData, errormsg);
if (sendto(socket, &errorpacket, sizeof(struct ERROR),0,
(struct sockaddr*)remoteaddr, remoteaddrsize) < 0)
{
printf("\n Error : Error Packet Send failed() ");
return -1;
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -