Overview

Two programs must be written, Message Sender and Message Collector. The Message Sender sends messages to all the Message Collectors it can find. The communication between the Message Sender and Message Collector used UDP and uses the Go-Back-N method for reliability. The Message Collector listens on port 10000 and the Message Sender sends from port 10001. (Use the same includes from project 1 along with #include <sys/timeb.h> and #include <time.h>)

Basic Tasks

Message Sender’s basic tasks are:

  1. Pick an IP address of possible Message Collector
  2. Make message
  3. Send message to collector in a reliable fashion (with Go-Back-N)
  4. Goto 1

The Message Collector collects messages from all message senders and saves them to disk. At users request, the message collector saves all collected messages to disk and exits. Basic steps for Message Collector’s basic tasks are:

  1. Check if segment arrived
    1. If segment arrived goto 2
    2. Else goto 3.
  2. Receive segment
  3. Check for user input (use kbhit())
    1. If user asks to end program, save collected messages to disk and exit
    2. Else goto 1

Message Sender details

The Message Sender holds an array of the message, broken up into segments. Each segment holds one character of data. Use the following structures.

struct SEGMENT {
            char Mess;       					// the data to be sent (only one character at a time)
            unsigned int SeqNum;               	// sequence number of this segment
            struct timeb Time;                   // the time this segment was sent
            unsigned NumTries;                  	// number of times this segment has been sent so far
            int ACKed;                         	// 1 if acked
};
Then the message is stored in an array:
	struct SEGMENT SegmentArray[MESSAGE_SIZE];            // the entire message
Set
	MESSAGE_SIZE = 300;
It is handy to have these as global variables:
	unsigned int NextToBeACKed;
	unsigned int NextToBeSent;
	unsigned int MessageLength;     // the size of the message

The function SendMessage takes DestIP as a parameter and performs these tasks:

1 Setup SegmentArray. Fill the Mess field to say something such as “hello.” Make sure to record MessageLength; Set NextToBeSent=0; NextToBeACKed=0;
2. while (NextToAcked< MessageLength)
 
a If (NextToBeSent < MessageLength) && (NextToBeSent-NextToBeACKed<N)
 
i. Send the segment at NextToBeSent to DestIP.
ii. Increment NextToBeSent’s number of tries (the number of tries to send this segment).
iii. Record that the segment has been sent (i.e., increment NextToBeSent) and the time it was sent.
b. Check if a packet is ready to be received (no waiting, timeout=0)
 
i. If ACK has arrived and the sequence number is greater or equal to the NextToBeAcked's sequence number
 
1. Mark all segments from NextToBeACKed to and including the sequence number in the ACK as ACKed.
2. Update NextToBeAcked.
3. If NextToAcked==MessageLength, then exit SendMessage function and print/record to disk that the message was successfully sent
c. If the time that NextToBeAcked was sent plus TimeOutTime is less than CurrentTime, then Go-Back-N
   
   

 

Message Collector details

The receiver uses the same packet structure along with GetNextPkt and MYIP

Use the follow structures.

struct MESSAGE {
            char SourceIP[80];                      // the source of the message
            char Message[MESSAGE_SIZE];           // the message itself
            int Rec[MESSAGE_SIZE];                  // if received or not
};
std::list<struct MESSAGE> ReceivedMessages;
unsigned NextMessage = 0; // this points to the next available    place in ReceivedMessages
char CurrentIP[80];

The psuedo-code is something like:

while (1)
{
	ret = GetNextPkt(UDPSock, &pkt, 0,0);
	if (ret>0)
	{
		std::list<struct MESSAGE>::iterator iter = FindMessageIndexOfThisSegement(ReceivedMessages, pkt.SourceIP);
		if (iter==NULL)
		{
  		Make new message and ReceivedMessages.push_front(	...)
			iter = ReceivedMessages.begin();
      }

		If received packet seq number is the next expected packet
		{
			Receive message
			Send ack
			If entire message has been received 
			{
				save message and sender's IP (make sure to call fflush(fptr) after fprintf)
				Print message to screen
				}
			}
		}
	}
}

 

So we can all communicate, we need a common packet format. Use this:

As a helper, here is GetNextPkt, a function to read a packet:

Note, GetNextPkt uses the global variable MYIP. Set MYIP in the beginning of the program with SetMYIP();

And here is a function to print the packet

A useful function to determine if a timeout has occurred GetTimeSinceLastACKed()

 

What to turn in: