/* * FILE: rdt_sender.cc * DESCRIPTION: Reliable data transfer sender. * VERSION: 0.2 * AUTHOR: Kai Shen (kshen@cs.rochester.edu) * NOTE: This implementation assumes there is no packet loss, corruption, or * reordering. You will need to enhance it to deal with all these * situations. In this implementation, the packet format is laid out as * the following: * * |<- 1 byte ->|<- the rest ->| * | payload size |<- payload ->| * * The first byte of each packet indicates the size of the payload * (excluding this single-byte header) */ #include #include #include #include "rdt_struct.h" #include "rdt_sender.h" /* sender initialization, called once at the very beginning */ void Sender_Init() { fprintf(stdout, "At %.2fs: sender initializing ...\n", GetSimulationTime()); } /* sender finalization, called once at the very end. you may find that you don't need it, in which case you can leave it blank. in certain cases, you might want to take this opportunity to release some memory you allocated in Sender_init(). */ void Sender_Final() { fprintf(stdout, "At %.2fs: sender finalizing ...\n", GetSimulationTime()); } /* event handler, called when a message is passed from the upper layer at the sender */ void Sender_FromUpperLayer(struct message *msg) { /* 1-byte header indicating the size of the payload */ int header_size = 1; /* maximum payload size */ int maxpayload_size = RDT_PKTSIZE - header_size; /* split the message if it is too big */ /* reuse the same packet data structure */ packet pkt; /* the cursor always points to the first unsent byte in the message */ int cursor = 0; while (msg->size-cursor > maxpayload_size) { /* fill in the packet */ pkt.data[0] = maxpayload_size; memcpy(pkt.data+header_size, msg->data+cursor, maxpayload_size); /* send it out through the lower layer */ Sender_ToLowerLayer(&pkt); /* move the cursor */ cursor += maxpayload_size; } /* send out the last packet */ if (msg->size > cursor) { /* fill in the packet */ pkt.data[0] = msg->size-cursor; memcpy(pkt.data+header_size, msg->data+cursor, pkt.data[0]); /* send it out through the lower layer */ Sender_ToLowerLayer(&pkt); } } /* event handler, called when a packet is passed from the lower layer at the sender */ void Sender_FromLowerLayer(struct packet *pkt) { } /* event handler, called when the timer expires */ void Sender_Timeout() { }