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>)
Message Sender’s basic tasks are:
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:
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) | ||||||||||||||||||||||||||||||
|
The receiver uses the same packet structure along with GetNextPkt and MYIP
Use the follow structure
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()