Introduction
Check out the source code on github.
This TCP-like reliable data transfer project is developed with two layers. The basic layer is UDP. MyUDPSocket
class is created as a wrapper of UDP transfer. For the other layer, SenderSocket
class is built on top of UDP and implements pipelined transfer, retransmit, timeout, flow control, etc in order to make the transfer reliable and efficient.
This project implements following properties of TCP.
- Send a window of packets. The transfer can be pipelined to improve efficiency.
- Flow control. The sender never overwhelms receiver.
- Timeout and retransmit.
- Fast retransmit. Packet is retransmitted upon receiving 3 duplicate ACKs.
- Timeout intervals are calculated accumulatively according to TCP formula.
Implementation
UDP layer
MyUDPSocket
is relatively simple. It implements SendTo()
and RecvFrom()
methods to do the job literally. Note the data transfer on both methods are unreliable and anything can happen.
reliable layer
SenderSocket
has Open()
method to initialize connection with the receiver side and Close()
method to close that connection. SYN, FIN and ACKs packets are used for this purpose.
For the actual data transfer, SenderSocket
owns three threads; one for sending packets, one for receiving ACKs, the last for Statistics. So that receiving doesn’t block sending.
Semaphores and events are used to ensure only one thread can access some critical sections.
Usage
The program takes 7 arguments as below.
transfer.exe target_host data_array_length_power window_size round_trip_time forward_loss reverse_loss link_rate
Sample trace
In the trace,
B
: the base of sender windowN
: next to sendT
: number of timeoutsF
: number of fast retransmissionsW
: effective windowS
: send speedRTT
: measured round trip time
Trace with no loss:
Main: sender W = 3000, RTT 0.010 sec, loss 0 / 0, link 10000 Mbps
Main: initializing DWORD array with 2^30 elements... done in 1566 ms
Main: connected to localhost in 0.011 sec, pkt size 1472 bytes
[ 2] B 163852 (228.8 MB) N 166852 T 0 F 0 W 3000 S 959.517 Mbps RTT 0.033
[ 4] B 344321 (480.7 MB) N 347320 T 0 F 0 W 3000 S 1056.826 Mbps RTT 0.033
[ 6] B 524254 (732.0 MB) N 527254 T 0 F 0 W 3000 S 1053.688 Mbps RTT 0.033
[ 8] B 704543 (983.7 MB) N 707543 T 0 F 0 W 3000 S 1055.772 Mbps RTT 0.033
[ 10] B 885070 (1235.7 MB) N 888070 T 0 F 0 W 3000 S 1057.166 Mbps RTT 0.034
[ 12] B 1064803 (1486.7 MB) N 1067803 T 0 F 0 W 3000 S 1052.516 Mbps RTT 0.035
[ 14] B 1244188 (1737.1 MB) N 1247188 T 0 F 0 W 3000 S 1050.479 Mbps RTT 0.034
[ 16] B 1424665 (1989.1 MB) N 1427665 T 0 F 0 W 3000 S 1056.873 Mbps RTT 0.032
[ 18] B 1608966 (2246.4 MB) N 1611965 T 0 F 0 W 3000 S 1079.267 Mbps RTT 0.032
[ 20] B 1792467 (2502.6 MB) N 1795467 T 0 F 0 W 3000 S 1074.582 Mbps RTT 0.034
[ 22] B 1976910 (2760.1 MB) N 1979910 T 0 F 0 W 3000 S 1080.098 Mbps RTT 0.032
[ 24] B 2161746 (3018.2 MB) N 2164746 T 0 F 0 W 3000 S 1082.400 Mbps RTT 0.032
[ 26] B 2345969 (3275.4 MB) N 2348969 T 0 F 0 W 3000 S 1078.810 Mbps RTT 0.034
[ 28] B 2531027 (3533.8 MB) N 2534027 T 0 F 0 W 3000 S 1083.700 Mbps RTT 0.032
[ 30] B 2714903 (3790.5 MB) N 2717902 T 0 F 0 W 3000 S 1076.778 Mbps RTT 0.032
[ 32] B 2896752 (4044.4 MB) N 2899751 T 0 F 0 W 3000 S 1064.908 Mbps RTT 0.035
[32.492] <-- FIN-ACK 2933721 window 39F2A0E6
Main: transfer finished in 32.404 sec, 1060354.84 Kbps, checksum 39F2A0E6
Main: estRTT 0.025, ideal rate 1424901.86 Kbps
Trace with small loss:
...\x64\Release> .\p3-reliable-data-transfer.exe localhost 20 50 0.01 0.1 0.0001 1000
Main: sender W = 50, RTT 0.010 sec, loss 0.1 / 0.0001, link 1000 Mbps
Main: initializing DWORD array with 2^20 elements... done in 2 ms
Main: connected to localhost in 0.011 sec, pkt size 1472 bytes
[ 2] B 626 ( 0.9 MB) N 676 T 16 F 43 W 50 S 3.666 Mbps RTT 0.011
[ 4] B 1208 ( 1.7 MB) N 1258 T 32 F 85 W 50 S 3.408 Mbps RTT 0.011
[ 6] B 1574 ( 2.2 MB) N 1624 T 53 F 112 W 50 S 2.143 Mbps RTT 0.011
[ 8] B 2148 ( 3.0 MB) N 2198 T 68 F 159 W 50 S 3.361 Mbps RTT 0.011
[ 10] B 2673 ( 3.7 MB) N 2723 T 83 F 201 W 50 S 3.074 Mbps RTT 0.011
[11.029] <-- FIN-ACK 2865 window 5B0360D
Main: transfer finished in 10.955 sec, 3062.93 Kbps, checksum 5B0360D
Main: estRTT 0.011, ideal rate 54531.69 Kbps