[Network programming/C ++] Summary of implementation of simple TFTP client (1) -- Interface Definition

Source: Internet
Author: User

After more than a day of research, the TFTP client has been easily implemented and some problems have been encountered in the project process. Most of the problems are due to the vague understanding of basic concepts such as C ++ type conversion, after receiving the deep-rooted influence of C language, my understanding of C ++'s inheritance and classes is still on paper. in practical use, I have some difficulties.

Now we will briefly analyze the process of implementing the TFTP client.

Through the TFTP protocol, we can know that the TFTP client has five types of datagram: read/write request packets, response packets, data packets, and error packets.

Based on the Protocol, we can define the structures of five types of packets as follows:

// TFTP header <br/> struct tftp_head <br/> {<br/> byte opcode [2]; <br/> byte block [2]; <br/> byte other [datasize]; <br/> }; </P> <p> // TFTP request package <br/> struct tftp_rrwq <br/>{< br/> byte opcode [2]; <br/> string filename; <br/> byte flag1; <br/> string mode; <br/> byte flag2; <br/> }; </P> <p>/data packets </P> <p> struct tftp_data <br/> {<br/> byte opcode [2]; <br/> byte blocknum [2]; <br/> byte data [datasize]; <br/> }; </P> <p> // Response Message <br/> struct tftp_ack <br/> {<br/> byte opcode [2]; <br/> byte blocknum [2]; <br/> }; </P> <p> // error data packet <br/> struct tftp_error <br/> {<br/> byte opcode [2]; <br/> byte errornum [2]; <br/> byte data [datasize]; <br/> byte flag; <br/>}; <br/>

 

Note: The establishment of tftp_head is mainly to determine the packet type during packet capture.

 

During the specific implementation of data packet transmission, I divided various operations into two interface classes: communication and data packet operations.

 

Communication:

# Define tftpport 69 </P> <p> class tftpconnectcontrol <br/> {<br/> word versionrequired; <br/> wsadata; <br/> socket clientsocket; <br/> sockaddr_in clientsock_in; </P> <p> Public: <br/> tftpconnectcontrol (); <br/> ~ Tftpconnectcontrol (); <br/> bool sendtotftpserver (char * senddata); <br/> bool recvtftppackage (char receivebuf [datasize + 4]); <br/> }; </P> <p> // version Verification <br/> tftpconnectcontrol: tftpconnectcontrol () <br/>{< br/> versionrequired = makeword (2, 2 ); <br/> int err = wsastartup (versionrequired, & wsadata); // version Verification <br/> If (! Err) <br/>{< br/> cout <"version Verification Successful! "<Endl; <br/>}< br/> else <br/>{< br/> cout <" version Verification Failed! "<Endl; <br/> return; <br/>}</P> <p> clientsocket = socket (af_inet, sock_dgram, ipproto_udp ); // create a UDP socket <br/> If (clientsocket = invalid_socket) // socket creation failed <br/>{< br/> cout <"invalid socket" <Endl; <br/> return; <br/>}< br/> memset (& clientsock_in, 0, sizeof (clientsock_in); <br/> clientsock_in.sin_family = af_inet; <br/> clientsock_in.sin_addr.s_un.s_addr = inet_addr ("***. ***. ***. * ** "); <br/> clientsock _ In. sin_port = htons (tftpport); <br/>}</P> <p> tftpconnectcontrol ::~ Tftpconnectcontrol () <br/>{< br/> closesocket (clientsocket); <br/> wsacleanup (); <br/> return; <br/>}</P> <p> // send data packets </P> <p> bool tftpconnectcontrol: sendtotftpserver (char * senddata) <br/>{ <br/> cout <"IP:" <inet_ntoa (clientsock_in.sin_addr) <Endl; <br/> cout <"Port: "<ntohs (clientsock_in.sin_port) <Endl; <br/> int err = sendto (clientsocket, senddata, sizeof (senddata), 0, (sockaddr *) & clientsock_in, sizeof (Sockaddr_in); // data packet transmission <br/> If (ERR = socket_error) // data transmission error <br/>{< br/> DWORD res = wsagetlasterror (); <br/> cout <"Transmission Error:" <res <Endl; <br/> // closesocket (clientsocket); <br/> return false; <br/>}< br/> cout <"data packet sent successfully! "<Endl; <br/> return true; <br/>}</P> <p> // receives data packets <br/> bool tftpconnectcontrol :: recvtftppackage (char receivebuf [datasize + 4]) <br/>{< br/> int Len = sizeof (sockaddr); <br/> int err = recvfrom (clientsocket, receivebuf, sizeof (receivebuf), 0, (sockaddr *) & clientsock_in, & Len); // receives data packets <br/> If (ERR = socket_error) <br/>{< br/> DWORD res = wsagetlasterror (); <br/> cout <"receiving error:" <res <Endl; <br/> return false; <br/>}</P> <p> return true; <br/>}< br/>

 

Data Packet processing:

 

// Determine whether the file is uploaded <br/> bool fileeof (byte datapack []) <br/> {<br/> return (strlen (const char *) datapack) <512 & strlen (const char *) datapack)> = 0 )? True: false; <br/>}</P> <p> class tftppackagecontrol <br/>{< br/> char tftpdata [datasize + 4]; // reserved buffer <br/> int recvblock; // receives the block number <br/> string filename; // file name </P> <p> public: <br/> tftppackagecontrol (string name); // constructor <br/> tftppackagecontrol (); // constructor 2 <br/> ~ Tftppackagecontrol (); // destructor <br/> void createtftprrq (); // create a file request package <br/> void createack (); // create an ACK packet <br/> bool recv_tftp_file (char * packagedata); // determine whether the file is transmitted <br/> bool dealwithdatapackage (char * datapackage ); // process data packets <br/> void setfilename (string name); <br/> char * gettftpdata (); <br/> }; </P> <p> // constructor <br/> tftppackagecontrol: tftppackagecontrol (string name) <br/>{< br/> memset (tftpdata, 0, size Of (tftpdata); <br/> recvblock = 0; <br/> filename = Name; <br/>}</P> <p> // constructor 2 <br/> tftppackagecontrol: tftppackagecontrol () <br/>{< br/> memset (tftpdata, 0, sizeof (tftpdata); <br/> recvblock = 0; <br/> filename = ""; </P> <p >}</P> <p> // structure <br/> tftppackagecontrol ::~ Tftppackagecontrol () <br/> {<br/> memset (tftpdata, 0, sizeof (tftpdata); <br/> recvblock = 0; <br/> filename = ""; <br/>}</P> <p> // set the recipient's file name <br/> void tftppackagecontrol: setfilename (string name) <br/>{< br/> filename = Name; <br/>}</P> <p> // create rrq data packet <br/> void tftppackagecontrol :: createtftprrq () <br/>{< br/> struct tftp_rrwq package; <br/> memset (package. opcode, 0x01, sizeof (package. opcode); <br/> package. filename. assign (filename); <br/> memset (& package. flag1, 0, sizeof (package. flag1); <br/> package. mode = "netascii"; // netascii for ASCII files, octet for binary files <br/> memset (& package. flag2, 0, sizeof (package. flag2); <br/> memcpy (tftpdata, (char *) & package, sizeof (Package )); <br/>}</P> <p> // create an ACK packet <br/> void tftppackagecontrol: createack () <br/>{< br/> struct tftp_ack * ackpackage = (struct tftp_ack *) malloc (sizeof (tftp_ack); <br/> memset (ackpackage-> opcode, 0x04, sizeof (ackpackage-> opcode); <br/> memset (ackpackage-> blocknum, recvblock, sizeof (ackpackage-> blocknum )); <br/> memcpy (tftpdata, (char *) & ackpackage, sizeof (ackpackage )); <br/>}</P> <p> // determines whether a data packet is received. <br/> bool tftppackagecontrol: recv_tftp_file (char * packagedata) <br/> {<br/> struct tftp_head * Data = (struct tftp_head *) packagedata; <br/> recvblock = (INT) * Data-> block; <br/> If (memcmp (data-> opcode, "0x03", sizeof (data-> opcode) <br/> return true; <br/> else <br/> return false; <br/>}</P> <p> char * tftppackagecontrol: gettftpdata () <br/>{< br/> return tftpdata; <br/>}</P> <p> // whether a file has been processed <br/> bool tftppackagecontrol :: dealwithdatapackage (char * datapackage) <br/>{< br/> char filedata [datasize]; <br/> struct tftp_data * Data = (struct tftp_data *) datapackage; <br/> memcpy (filedata, data-> data, sizeof (data-> data); </P> <p> ofstream fout; <br/> fout. open (filename. c_str (); <br/> fout <filedata; <br/> fout. close (); <br/> return fileeof (data-> data); </P> <p>}

 

Of course, this is only the initial design of the TFTP client. It will be improved as the project progresses and will be recorded here for the time being. (* ^__ ^ *)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.