Reliable Data Transfer Protocol
description
Transcript of Reliable Data Transfer Protocol
Reliable Data Transfer ProtocolIMPLEMENTATION TIPS
Transport Layer – TCP2
B
Recall Reliable Data Transfer Mechanisms:
Checksum
Timer
Sequence number
ACK NAK
Window, pipelining
socketdoor
TCPsend buffer
TCPreceive buffer
socketdoor
Packet ->
applicationwrites data
applicationreads data
- Verification of integrity of packet
- Signals necessary re-transmission is required
- Keeps track of which packet has been sent and received
- Indicates receipt of packet in good or bad form
- Allows for the sending of multiple yet-to-be-acknowledged packets
Client - ServerCLIENT
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Windows.txt
SERVER
Empty...
File1_Saved.txt
Rclient_UDP.cpp Rserver_UDP.cpp
socket socket
UDP (User Datagram Protocol)– has no connection establishment- No connection state at servers- less packet overhead than TCP- light error-checking (checksum)- server doesn’t use the listen() function- server doesn’t use the accept() function
• See Lecture-2012-6-Socket Programming-Part2 (Slide #4)
UDP Basics
Client - ServerCLIENT
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Windows.txt
SERVER
Empty...
File1_Saved.txt
Rclient_UDP.cpp Rserver_UDP.cpp
socket socket
Rserver 1235 0 0Rclient 127.0.0.1 1235 0 0
You should run the server first, before running the client. You can test your client and server using the same machine by using the example run above.
Sample run:
Bits can be corrupted Packets can be lost
Port: 1235
Client - ServerCLIENT
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Windows.txt
SERVER
Empty...
File1_Saved.txt
Rclient_UDP.cpp Rserver_UDP.cpp
socket socket
Rserver 1235 0 0Rclient 127.0.0.1 1235 0 0
The client is the sender, while the server is the receiver.
The filenames used for sending and saving have been fixed in the start-up codes (i.e. File1_Windows.txt, File1_Saved.txt).
Client - ServerCLIENT
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Windows.txt
SERVER
Empty...
File1_Saved.txt
Rclient_UDP.cpp Rserver_UDP.cpp
socket socket
Rserver 1235 0 0Rclient 127.0.0.1 1235 0 0
The client sends the contents of the file line by line. One packet contains exactly one line. In order to implement reliable data transfer, you will have to modify the packet header to add more details.
Client - ServerCLIENT
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Windows.txt
SERVER
Empty...
File1_Saved.txt
Rclient_UDP.cpp Rserver_UDP.cpp
socket socket
Rserver 1235 0 0Rclient 127.0.0.1 1235 0 0
The objective is for you to implement a reliable data transfer protocol. You can choose to implement a simple stop-and-wait protocol or any of the pipe-lining protocols (i.e. Go Back-N, Selective Repeat).
Client - ServerCLIENT
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Windows.txt
SERVER
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Saved.txt
Rclient_UDP.cpp Rserver_UDP.cpp
socket socket
Receives file contentsline-by-line, then stores everythinginto a file
Reads file, then sends the contents1 line at a time
UNRELIABLE CHANNELNETWORK LAYER
TRANSPORT LAYER
APPLICATION LAYER
Client - ServerCLIENT
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Windows.txt
SERVER
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Saved.txt
Rclient_UDP.cpp Rserver_UDP.cpp
socket socket
Receives file contentsline-by-line, then stores everythinginto a file
Reads file, then sends the contents1 line at a time
UNRELIABLE CHANNELNETWORK LAYER
TRANSPORT LAYER
APPLICATION LAYER
Simulated by a function named send_unreliably()
Unreliable Channel Simulationint send_unreliably( int s, char * send_buffer, struct sockaddr_in remoteaddress) {
int fate=packets_fate(); //random number generator: 0, 1, 2 if (fate==0){ //no problem will be introduced
bytes = sendto(s, send_buffer, ...)printf("<-- SEND: %s \n",send_buffer);
} else if (fate== 1){ // introduce corrupted bitssend_buffer[damage_bit()]=random_char();send_buffer[damage_bit()]=random_char();bytes = sendto(s, send_buffer, ...)printf("<-- DAMAGED %s \n",send_buffer);…
} else if(fate==2){ // lose the packetprintf("X-- LOST %s \n",send_buffer);
}}
You are not allowed to modify this function in the
assignment.
UDP segment structure
• The optional parameters are not even included in the sendto() function.
Optional in IPv4
int sendto( SOCKET s, char *buf, int msglen, int flags, struct sockaddr *to, int tolen);
• The O/S will automatically provide the IP address of the sender of the segment.
•Send data through a socket:sendto(SOCKET s, char *msg, int msglen, int flags,
struct sockaddr *to, int *tolen);
sendto()
Example:
sendto(s, sbuffer, strlen(sbuffer),0,(struct sockaddr*) to, &len);
s = socket (inside the socket descriptor: port and IP address...)msg = a pointer to a buffer (could be a string)msglen = the length of the bufferflags = 0 (forget about them for this exercise...)to=structure of address with the IP / port #tolen=length of the structure
PARAMETERS
14
Receive dataint recvfrom(SOCKET s, char *msg, int msglen,
int flags, struct sockaddr *from, int *fromlen)
recvfrom()
Example:
recvfrom(s, rbuffer, 1, 0,(struct sockaddr *) &from, &len);
s = socket (inside the socket descriptor: port and IP address...)msg = a pointer to a buffermsglen = the length of the bufferflags = 0from =structure of address with the IP / port #fromlen=length of the structure
PARAMETERS
Client - ServerCLIENT
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Windows.txt
SERVER
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Saved.txt
Rclient_UDP.cpp Rserver_UDP.cpp
socket socket
Receives file contentsline-by-line, then stores into a file
Destination Port: 1235 DATAchecksum Length of segment
Reads file, then sends the contents1 line at a time
UDP SEGMENT
Client - ServerCLIENT
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Windows.txt
SERVER
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Saved.txt
Rclient_UDP.cpp Rserver_UDP.cpp
socket socket
Receives file contentsline-by-line, then stores into a file
Destination Port: 1235 DATA
0 ABCDEF
checksum Length of segment
Reads file, then sends the contents1 line at a time
PACKET 0 ‘\r’ ‘\n’CRC_NUMUser-defined
Start-up Codes(Client-Server)
Let’s have a look at the CRC function provided as part of the start-up codes and the CRC test program.
CRC
//*******************************************************************// CREATE CLIENT'S SOCKET //******************************************************************* s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { printf("socket failed\n"); WSACleanup(); exit(1); }
//nonblocking option u_long iMode=1; ioctlsocket(s, FIONBIO, &iMode);
Socket (in non-blocking mode)
• We need to set our socket in non-blocking mode of operation.• This prevents the recvfrom() function from stopping and waiting for a packet.• Remember, packets could be lost in our simulation of the unreliable channel.
Start-up Codes (Client – Server)CLIENT
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Windows.txt
SERVER
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Saved.txt
Rclient_UDP.cpp Rserver_UDP.cpp
socket socket
Receives file contentsline-by-line, then stores into a file
Reads file using fgets(), then sends the contents 1 line at a time
Loop: send_unreliably(data) recvfrom()
Loop: recvfrom() send_unreliably(ACK)
fopen(“file1_Windows.txt”, r) fopen(“file1_Saved”, w)
Reading the file contentsThe client reads the file contents line by line using fgets()
fgets(send_buffer, SEGMENT_SIZE, fin)• stops reading the file when it encounters either:
• a new line character (copied into send_buffer)• EOF (End-Of-File) character
• a NULL-termination character (‘\0’) is automatically appended• this is counted as one of the characters
strlen() – counts the number of characters excluding the NULL-character
CLIENT
ABC
‘\n’
‘\0’
send_buffer
strlen()=4
‘\0’
‘\0’
send_buffer
strlen()-1
0
1
2
34
0
1
2
34
ABC
Data FormatCLIENT
ABC
‘\n’
‘\0’
send_buffer
strlen()=4
‘\0’
‘\0’
send_buffer
strlen()-1
0
1
2
34
0
1
2
34
ABC
Destination Port: 1235 DATA
ABC
checksum Length of segment
PACKET 0 ‘\r’ ‘\n’CRC_NUMUser-defined
Remove the line feed character from the row of data read from the file
CLIENT
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Windows.txt
SERVER
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Saved.txt
Rclient_UDP.cpp Rserver_UDP.cpp
socket socket
Loop: send_unreliably(data) recvfrom()
Loop: recvfrom() send_unreliably(ACK)
fopen(“file1_Windows.txt”, r) fopen(“file1_Saved”, w)
send_unreliably(”CLOSE”)closesocket() Write everything into file1_Saved.txt
fclose()closesocket()
Start-up Codes (Client – Server)
Let’s see more details...
Start-up Codes (Client – Server)CLIENT SERVER
Loop: read one line from file if(not EOF){ create packet with header fields store packet into send_buffer send_unreliably(send_buffer) Sleep(1); recvfrom(receive_buffer) trim ‘\r’, ‘\n’ from receive_buffer } else { fclose() send_unreliably(”CLOSE”) }
Loop: recvfrom(receive_buffer) trim ‘\r’, ‘\n’ from receive_buffer process receive_buffer if(receive_buffer contains DATA){ create ACK packet send_unreliably(ACK) save_line_without_header } else { fclose() }
fopen(“file1_Windows.txt”, r) fopen(“file1_Saved”, w)
closesocket()closesocket()
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
Let’s have a look at the Start-up Codes (downloadable from our website)
Start-up Codes
Recommended Way of Testing
the Codes(Client-Server)
Parameters Settings
Parameters (Client – Server)CLIENT SERVER
Rclient_UDP.cpp Rserver_UDP.cpp
Rserver 1235 0 0Rclient 127.0.0.1 1235 0 0Sample run:
Bits can be corrupted
Packets can be lost
CLIENT SERVER COMMENTS
00 00 Packets can never be corrupted nor lost
01 00 Client may lose packets
00 01 Server may lose ACK packets
01 01 Both client and server may lose packets
10 00 Client may have corrupt bits
00 10 Server may have corrupt bits
10 10 Both client and server may have corrupted bits
11 11 Both client and server may have corrupted bits and may lose packets
Ultimate TestCLIENT SERVER
Rclient_UDP.cpp Rserver_UDP.cpp
Rserver 1235 1 1Rclient 127.0.0.1 1235 1 1
Ultimate Test:
Bits can be corrupted
Packets can be lost
You can simply inspect the contents of File1_Windows.txt and File1_Saved.txt, to check to see if they are exactly the same.
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Windows.txt0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
File1_Saved.txt
Adding data transfer reliability
Extending the codes
Let’s have a look at the Go-Back N Protocol Specifications…
See Lecture-2012-7-Transport Layer-Part-1 (Slide #37)
Go-Back N
Pipelining Protocol (Go Back-N)CLIENT
(sender)
base base + (N-1)
ABCPACKET 0 ‘\r’ ‘\n’CRC_NUM ABCPACKET 1 ‘\r’ ‘\n’CRC_NUM ABCPACKET 2 ‘\r’ ‘\n’CRC_NUM
Send a Window’s worth of packets
N=Window size = 4
Sequence Number Space
Pipelining Protocol (Go Back-N)
base base + (N-1)
ABCPACKET 0 ‘\r’ ‘\n’CRC_NUM ABCPACKET 1 ‘\r’ ‘\n’CRC_NUM ABCPACKET 2 ‘\r’ ‘\n’CRC_NUM
Send a Window’s worth of packets
N = Window size = 4
nextSequenceNum-1Packets sent but not yet ACKed
...
nextSequenceNum
CLIENT (sender)
Pipelining Protocol (Go Back-N)
base base + (N-1)
N = Window size = 4
nextSequenceNum-1
Packets sent but not yet ACKed
nextSequenceNum
base baseMax
ACKnum
We need to keep track of the ACK number received
CLIENT (sender)
Pipelining Protocol (Go Back-N)
N = Window size = 4
Upon receipt of an ACK, slide the window forward
base=0 baseMax=3
ACKnum=1
base=ACKnum+1baseMax=base+(N-1)
0 1 2 3
0 1 2 3 4 5
time=0
time=1
CLIENT (sender)
Pipelining Protocol (Go Back-N)
N = Window size = 4
Transmit more packets (up to baseMax)base=0 baseMax=3
ACKnum=1
base=ACKnum+1baseMax=base+(N-1)
0 1 2 3
0 1 2 3 4 5
time=0
time=2
CLIENT (sender)
Extending the codes
WARNING: The following pseudo codes are not complete. They are meant just to give you an idea of how to implement a sliding Window protocol.
The statements highlighted in red corresponds to the suggested routines that need to be incorporated.
38
Calculating the Elapsed Timeclock()
void wait ( int seconds ){ clock_t endwait;
endwait = clock () + seconds * CLOCKS_PER_SEC ; while (clock() < endwait) {}}
clock_t startTime, elapsedTime;
startTime = clock();…...elapsedTime = (clock() - startTime) / CLOCKS_PER_SEC;
Extending the codes
Loop: read one line from file if(not EOF){ create packet with header fields store packet into send_buffer send_unreliably(send_buffer) Sleep(1); recvfrom(receive_buffer) trim ‘\r’, ‘\n’ from receive_buffer extract ACK number update base, baseMax } else { fclose() send_unreliably(”CLOSE”) }
Loop: recvfrom(receive_buffer) trim ‘\r’, ‘\n’ from receive_buffer extract CRC1 from receive_buffer extract data from receive_buffer calc CRC2 using data if(CRC1 == CRC2){ extract Packet Num if(PacketNum is in-order){ if(receive_buffer contains DATA){ create ACK packet send_unreliably(ACK) save_line_without_header update expectedSeqNum, base } else if(receive_buffer contains CLOSE) { fclose(); closesocket(); } } }
fopen(“file1_Windows.txt”, r) fopen(“file1_Saved”, w)
closesocket()
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
0 ABCDEF1 ABCDEF2 ABCDEF3 ABCDEF...
SERVERCLIENT
Other Helpful Functions
strchr• <cstring>• const char * strchr ( const char * str, int character ); char *
strchr ( char * str, int character );• Locate first occurrence of character in string• Returns a pointer to the first occurrence of character in the C
string str.
The terminating null-character is considered part of the C string. Therefore, it can also be located to retrieve a pointer to the end of a string.