Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

FILL IN THE BLANKS TO THE GIVEN CLIENT AND SERVER C PROGRAMS FOR THE FOLLOWING QUESTION. CLIENT CODE: #include #include #include #include #include #include #include

FILL IN THE BLANKS TO THE GIVEN CLIENT AND SERVER C PROGRAMS FOR THE FOLLOWING QUESTION.

image text in transcribedimage text in transcribedimage text in transcribed

CLIENT CODE:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "lab5.h"

// NOTE: beware of sign extension if the checksum is stored in a char, then converted to an int!

int getChecksum(Packet packet) {

packet.header.cksum = 0;

int checksum = 0;

char *ptr = (char *)&packet;

char *end = ptr + sizeof(Header) + packet.header.len;

//Please find an error from the remaining part getChecksum() function

//******FILL CODE HERE ******

while (ptr

checksum ^= ptr++;

}

return checksum;

}

void logPacket(Packet packet) {

printf("Packet{ header: { seq_ack: %d, len: %d, cksum: %d }, data: \"",

packet.header.seq_ack,

packet.header.len,

packet.header.cksum);

fwrite(packet.data, (size_t)packet.header.len, 1, stdout);

printf("\" } ");

}

void ClientSend(int sockfd, const struct sockaddr *address, socklen_t addrlen, Packet packet) {

while (1) {

// send the packet

printf("Sending packet ");

//******FILL CODE HERE******

// receive an ACK from the server

Packet recvpacket;

//******FILL CODE HERE******

// log what was received

printf("Received ACK %d, checksum %d - ", recvpacket.header.seq_ack, recvpacket.header.cksum);

// validate the ACK

if ( //*****FILL CODE HERE***** ) {

// bad checksum, resend packet

printf("Bad checksum, expected checksum was: %d ", //******FILL CODE HERE******);

} else if ( //******FILL CODE HERE******) {

// incorrect sequence number, resend packet

printf("Bad seqnum, expected sequence number was: %d ", //******FILL CODE HERE*****);

} else {

// good ACK, we're done

printf("Good ACK ");

break;

}

}

printf(" ");

}

int main(int argc, char *argv[]) {

// check arguments

if (argc != 4) {

fprintf(stderr, "Usage: %s ", argv[0]);

return 1;

}

// seed the RNG

srand((unsigned)time(NULL));

// create and configure the socket [name the socket sockfd]

//******FILL CODE HERE******

// initialize the server address structure using argv[2] and argv[1]

struct sockaddr_in address;

memset(&address, 0, sizeof(address));

//******FILL CODE HERE******

// open file using argv[3]

//******FILL CODE HERE******

// send file contents to server

//-create a packet

//-set the seq_ack field

//-set the len field

//-calculate the checksum

//-send the packet

//******FILL CODE HERE******

// send zero-length packet to server to end connection

//******FILL CODE HERE******

// clean up

//-close the sockets and file

//******FILL CODE HERE******

return 0;

}

SERVER CODE:

#include

#include

#include

#include

#include

#include

#include

#include "lab5.h"

// NOTE: beware of sign extension if the checksum is stored in a char, then converted to an int!

int getChecksum(Packet packet) {

packet.header.cksum = 0;

int checksum = 0;

char *ptr = (char *)&packet;

char *end = ptr + sizeof(Header) + packet.header.len;

//Please find an error from the remaining part getChecksum() function

//******FILL CODE HERE******

while (ptr

checksum ^= ptr++;

}

return checksum;

}

void logPacket(Packet packet) {

printf("Packet{ header: { seq_ack: %d, len: %d, cksum: %d }, data: \"",

packet.header.seq_ack,

packet.header.len,

packet.header.cksum);

fwrite(packet.data, (size_t)packet.header.len, 1, stdout);

printf("\" } ");

}

//Sending a ACK to the client, i.e., letting the client know what was the status of the packet it sent.

void ServerSend(int sockfd, const struct sockaddr *address, socklen_t addrlen, int seqnum) {

Packet packet;

//-Prepare the packet headers

//-send the packet

//******FILL CODE HERE******

printf("Sent ACK %d, checksum %d ", packet.header.seq_ack, packet.header.cksum);

}

Packet ServerReceive(int sockfd, struct sockaddr *address, socklen_t *addrlen, int seqnum) {

Packet packet;

while (1) {

//recv packets from the client

//******FILL CODE HERE******

// log what was received

printf("Received: ");

logPacket(packet);

if ( //******FILL CODE HERE******) {

printf("Bad checksum, expected checksum was: %d ", //******FILL CODE HERE******);

ServerSend(sockfd, address, *addrlen, !seqnum);

} else if (packet.header.seq_ack != seqnum) {

printf("Bad seqnum, expected sequence number was:%d ", //******FILL CODE HERE******);

//******FILL CODE HERE******

} else {

printf("Good packet ");

//******FILL CODE HERE******

break;

}

}

printf(" ");

return packet;

}

int main(int argc, char *argv[]) {

// check arguments

if (argc != 3) {

fprintf(stderr, "Usage: %s ", argv[0]);

return EXIT_FAILURE;

}

// seed the RNG

srand((unsigned)time(NULL));

// create a socket

//******FILL CODE HERE******

// initialize the server address structure using argv[1]

struct sockaddr_in address;

//******FILL CODE HERE******

// bind the socket

// [Question]: Do we need to bind the socket on the client side? Why?/Why not?

//******FILL CODE HERE*****

// open file using argv[2]

//******FILL CODE HERE******

// get file contents from client

int seqnum = 0;

Packet packet;

struct sockaddr_in clientaddr;

socklen_t clientaddr_len = sizeof(clientaddr);

do {

packet = ServerReceive( //******FILL CODE HERE****** );

//******FILL CODE HERE******

} while (packet.header.len != 0);

fclose(file);

close(sockfd);

return 0;

}

Objective 1. To build a Stop and Wait reliable protocol on top of UDP to provide a reliable transport service TFv2 - Stop and wait for an Unreliable Channel In Lab 3, you have developed a UDP client/server to transfer file, let us name it as TFV1. To ensure a reliable transfer, you need to implement a reliable Stop and Wait protocol. This version of file transfer is then TFv2. TFv2 is going to be built on top of UDP, and it is supposed to provide a reliable transport service to TFv1 (developed in week 3, which needs to change to call your new send and receive functions and use buffers of same size). Messages are sent one at a time, and each message needs to be acknowledged when received, before a new message can be sent. TFV2 implements basically the protocol rdt2.2 presented in the text book (depicted as well at the end of this document). TFv2 consists of a client and a server. Communication is unidirectional, i.e., data flows from the client to the server. The server starts first and waits for messages. The client starts the communication. Messages have seq number 0 or 1. Before sending each message, a 1-byte checksum is calculated and added to the header. After sending each message, the client waits for a corresponding ACK. When it arrives, if it is not the corresponding ACK (or if the checksum does not match), the message is sent again. If it is the corresponding ACK, the client changes state and returns to the application, which can now send one more message. This means that TFV2 blocks on writes until an ACK is received. The server, after receiving a message, checks its checksum. If the message is correct and has the right seq number, the server sends an ACKO or ACK1 message (according to the seq number) to the client, changes state accordingly, and deliver data to the application. The protocol should deal properly with duplicate data messages and duplicate ACK messages. Follow the FSM in the book! TFV2 message contains the header and the application data. No reordering is necessary, since TFv2 is sending the exact message given by the application, one by one. The checksum must be calculated for messages from the server and client. To calculate the checksum, calculate the XOR off all the bytes (header or header + data) when member cksum (see below) is zero. To verify your protocol, use the result of a random function to decide whether to send the right checksum or just zero. This will fake the error effect. PROTOCOL HEADER seq_ack len cksum int (32 bits) int (32 bits) int (32 bits) // SEQ for data and ACK for Acknowledgement // Length of the data in byes (zero for ACKS) // Checksum calculated (by byte) PACKET header data char (10 bytes) SENDER Member seq_ack is used as SEQ, and the data is in member data. Each packet may have 10 or less bytes of data, and the sender only sends the necessary bytes. After transmitting the file, a packet with no data (len = 0) is sent to notify the receiver that the file is complete. RECEIVER Member seq_ack is used as ACK, and data is empty (len = 0). rdt2.2 sender - FSM rdt_send (data) sndpkt=make_pkt(0, data, checksum) udt_send (sndpkt) rdt_rev (rcvpkt) && (corrupt (revpkt) Il iSACK (rcvpkt,1)) udt_send (sndpkt) Wait for call 0 from above Wait for rdt_rev (rcvpkt) && notcorrupt (rcvpkt) && iSACK (rcvpkt,1) rdt_rcy (rcvpkt) && notcorrupt (rcvpkt) && iSACK (rcvpkt,0) Wait for ACK 1 Wait for call 1 from above rdt_rev (rovpkt) && (corrupt (rcvpkt)l iSACK (rovpkt,0)) udt_send (sndpkt) rdt_send(data) sndpkt-make_pkt(1, data, checksum) udt_send(sndpkt) rdt2.2 receiver - FSM rdt_rev (rcvpkt) && notcorrupt (rcvpkt) && has_seq0 (rcvpkt) extract (rovpkt, data) deliver_data (data) sndpkt-make_pkt (ACK, 0, checksum) udt_send (sndpkt) rdt_rev (rcvpkt) && (corrupt (rcvpkt) | has_sego (rcvpkt)) sndpkt=make_pkt (ACK, 0, checksum) udt_send (sndpkt) rdt_rev (rcvpkt) && (corrupt (revpkt) has_seql (revpkt)) Wait for O from below Wait for 1 from below sndpkt=make_pkt (ACK, 1, checksum) udt_send (sndpkt) rdt_rev (rcvpkt) && notcorrupt (revpkt) & & has_seq1 (rcvpkt) extract (rcypkt, data) deliver_data (data) sndpkt=make_pkt (ACK, 1, checksum) udt_send(sndpkt) Objective 1. To build a Stop and Wait reliable protocol on top of UDP to provide a reliable transport service TFv2 - Stop and wait for an Unreliable Channel In Lab 3, you have developed a UDP client/server to transfer file, let us name it as TFV1. To ensure a reliable transfer, you need to implement a reliable Stop and Wait protocol. This version of file transfer is then TFv2. TFv2 is going to be built on top of UDP, and it is supposed to provide a reliable transport service to TFv1 (developed in week 3, which needs to change to call your new send and receive functions and use buffers of same size). Messages are sent one at a time, and each message needs to be acknowledged when received, before a new message can be sent. TFV2 implements basically the protocol rdt2.2 presented in the text book (depicted as well at the end of this document). TFv2 consists of a client and a server. Communication is unidirectional, i.e., data flows from the client to the server. The server starts first and waits for messages. The client starts the communication. Messages have seq number 0 or 1. Before sending each message, a 1-byte checksum is calculated and added to the header. After sending each message, the client waits for a corresponding ACK. When it arrives, if it is not the corresponding ACK (or if the checksum does not match), the message is sent again. If it is the corresponding ACK, the client changes state and returns to the application, which can now send one more message. This means that TFV2 blocks on writes until an ACK is received. The server, after receiving a message, checks its checksum. If the message is correct and has the right seq number, the server sends an ACKO or ACK1 message (according to the seq number) to the client, changes state accordingly, and deliver data to the application. The protocol should deal properly with duplicate data messages and duplicate ACK messages. Follow the FSM in the book! TFV2 message contains the header and the application data. No reordering is necessary, since TFv2 is sending the exact message given by the application, one by one. The checksum must be calculated for messages from the server and client. To calculate the checksum, calculate the XOR off all the bytes (header or header + data) when member cksum (see below) is zero. To verify your protocol, use the result of a random function to decide whether to send the right checksum or just zero. This will fake the error effect. PROTOCOL HEADER seq_ack len cksum int (32 bits) int (32 bits) int (32 bits) // SEQ for data and ACK for Acknowledgement // Length of the data in byes (zero for ACKS) // Checksum calculated (by byte) PACKET header data char (10 bytes) SENDER Member seq_ack is used as SEQ, and the data is in member data. Each packet may have 10 or less bytes of data, and the sender only sends the necessary bytes. After transmitting the file, a packet with no data (len = 0) is sent to notify the receiver that the file is complete. RECEIVER Member seq_ack is used as ACK, and data is empty (len = 0). rdt2.2 sender - FSM rdt_send (data) sndpkt=make_pkt(0, data, checksum) udt_send (sndpkt) rdt_rev (rcvpkt) && (corrupt (revpkt) Il iSACK (rcvpkt,1)) udt_send (sndpkt) Wait for call 0 from above Wait for rdt_rev (rcvpkt) && notcorrupt (rcvpkt) && iSACK (rcvpkt,1) rdt_rcy (rcvpkt) && notcorrupt (rcvpkt) && iSACK (rcvpkt,0) Wait for ACK 1 Wait for call 1 from above rdt_rev (rovpkt) && (corrupt (rcvpkt)l iSACK (rovpkt,0)) udt_send (sndpkt) rdt_send(data) sndpkt-make_pkt(1, data, checksum) udt_send(sndpkt) rdt2.2 receiver - FSM rdt_rev (rcvpkt) && notcorrupt (rcvpkt) && has_seq0 (rcvpkt) extract (rovpkt, data) deliver_data (data) sndpkt-make_pkt (ACK, 0, checksum) udt_send (sndpkt) rdt_rev (rcvpkt) && (corrupt (rcvpkt) | has_sego (rcvpkt)) sndpkt=make_pkt (ACK, 0, checksum) udt_send (sndpkt) rdt_rev (rcvpkt) && (corrupt (revpkt) has_seql (revpkt)) Wait for O from below Wait for 1 from below sndpkt=make_pkt (ACK, 1, checksum) udt_send (sndpkt) rdt_rev (rcvpkt) && notcorrupt (revpkt) & & has_seq1 (rcvpkt) extract (rcypkt, data) deliver_data (data) sndpkt=make_pkt (ACK, 1, checksum) udt_send(sndpkt)

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Modern Database Management

Authors: Heikki Topi, Jeffrey A Hoffer, Ramesh Venkataraman

13th Edition

0134773659, 978-0134773650

More Books

Students also viewed these Databases questions

Question

How organized or ready for action on this issue is this public?

Answered: 1 week ago

Question

What does this public know about your organization?

Answered: 1 week ago

Question

What does this public expect from your organization?

Answered: 1 week ago