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
  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
    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 to define a structure.

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[300];            // the entire message
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;
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 equals the NextToBeAcked's sequence number
 
1. Mark segment as ACKed.
2. Update NextToBeAcked.
3. If NextToAcked==MessageLength, then exit SendMessage function and record 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
};
struct MESSAGE ReceivedMessages[MESSAGE_ARRAY_SIZE];
unsigned NextMessage = 0; // this points to the next available    place in ReceivedMessages
char CurrentIP[80];
struct timeb LastTime;
LastTime = CurrentTime-5seconds;

The psuedo-code is something like:

while (1)
{
	ret = GetNextPkt(UDPSock, &pkt, 0,0);
	if (ret>0)
	{
		int    I = FindMessageIndexOfThisSegement(pkt.SourceIP);
		if (pkt.SourceIP!=CurrentIP) && (LastTime+5seconds<CurrentTime)
			NextMessage=0;
		If received packet seq number is the next expected packet
		{
			Receive message
			Send ack
			If entire message has been received (i.e., just received message = 0)
			{
				save message and sender's IP (make sure to call fflush(fptr) after fprintf)
				Print message to screen
				NextMessage=0;
				}
			}
	}
}

 

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()