Bachelor of Science in Computer Science with specialization in Game Programming June 2017

The impact of transport protocol, packet size, and connection type on the round trip time

Tobias Kling

Faculty of Computing Blekinge Institute of Technology SE–371 79 Karlskrona, Sweden

i This thesis is submitted to the Faculty of Computing at Blekinge Institute of Technology in partial fulfillment of the requirements for the degree of Degree of Bachelor of Science in Computer Science with specialization in Game Programming. The thesis is equivalent to 10 weeks of full-time studies.

Contact Information: Author(s): Tobias Kling E-mail: [email protected]

University Advisor: Francisco Lopez Luro Department of Creative Technologies

Faculty of Computing Internet : www.bth.se Blekinge Institute of Technology Phone : +46 455 38 50 00 SE–371 79 Karlskrona, Sweden Fax : +46 455 38 50 57 Abstract

While developing networking for games and applications, developers have a list of network specific requirements to be met as well as decide how to meet them. It is not always easy to decide what protocol is best suited for a given network configuration, or what is the best size of a data packet. By performing a comparative analysis, it becomes possible to identify how proto- cols, packet size, and network configuration impact the one-way travel time and throughput of a given implementation. The result shows how the different implementations compared against each other and the analysis tries to determine why they perform as they do. This gives a good overview of the pros and cons of how TCP, TCP(N), UDP, and RakNet, behave and perform over LANs and WLANs with varying packet size.

Keywords: Transport protocol, Network Configuration, Packet Size, Comparison ii List of Figures

5.1 Ethenet TCP Delay Results ...... 12 5.2 Ethenet TCP(N) Delay Results ...... 13 5.3 Ethenet RakNet Delay Results ...... 13 5.4 Ethenet UDP Delay Results ...... 14 5.5 Switch TCP Delay Results ...... 15 5.6 Switch TCP(N) Delay Results ...... 16 5.7 Switch RakNet Delay Results ...... 16 5.8 Switch UDP Delay Results ...... 17 5.9 Private wifi TCP Delay Results ...... 18 5.10 Private wifi TCP(N) Delay Results ...... 19 5.11 Private wifi RakNet Delay Results ...... 19 5.12 Private wifi UDP Delay Results ...... 20 5.13 Public wifi TCP Delay Results ...... 21 5.14 Public wifi TCP(N) Delay Results ...... 22 5.15 Public wifi RakNet Delay Results ...... 22 5.16 Public wifi UDP Delay Results ...... 23 5.17 TCP Throughput Results ...... 24 5.18 Ethernet TCP(N) Throughput Results ...... 25 5.19 Ethernet RakNet Throughput Results ...... 25 5.20 Ethernet UDP Throughput Results ...... 26 5.21 Switch TCP Throughput Results ...... 27 5.22 Switch TCP(N) Throughput Results ...... 28 5.23 Switch RakNet Throughput Results ...... 28 5.24 Switch UDP Throughput Results ...... 29 5.25 Private wifi TCP Throughput Results ...... 30 5.26 Private wifi TCP(N) Throughput Results ...... 31 5.27 Private wifi RakNet Throughput Results ...... 31 5.28 Private wifi UDP Throughput Results ...... 32 5.29 Public wifi TCP Throughput Results ...... 33 5.30 Public wifi TCP(N) Throughput Results ...... 34 5.31 Public wifi RakNet Throughput Results ...... 34

iii Contents

List of Figures iii

1 Introduction 1 1.1 Background ...... 1 1.2 Problem Description ...... 1 1.3 The Scope of the Thesis ...... 1 1.4 Research Question ...... 2

2 Previous Work 3

3 Theory 4 3.1 What impacts the problem ...... 4 3.2 Network Configuration ...... 4 3.3 Network Transport Protocols ...... 5 3.4 Packet Size ...... 6

4 Method 7 4.1 Method Description ...... 7 4.2 Execution ...... 8 4.3 Expected Results ...... 10

5 Result 11 5.1 Delay Results ...... 12 5.1.1 Ethernet ...... 12 5.1.2 Switch ...... 15 5.1.3 Private Wifi ...... 18 5.1.4 Public Wifi ...... 21 5.2 Throughput Results ...... 24 5.2.1 Ethernet ...... 24 5.2.2 Switch ...... 27 5.2.3 Private wifi ...... 30 5.2.4 Public Wifi ...... 33

6 Analysis 35 6.1 Packet Travel Time Test ...... 35 6.2 Throughput Test ...... 37

iv 7 Conclusion 39 7.1 Summary ...... 39 7.2 Future Work ...... 40

A Bachelor Networking 43 A.1 main.cpp ...... 43 A.2 NetworkService.h ...... 55 A.3 NetworkService.cpp ...... 56 A.4 NetworkData.h ...... 57 A.5 WinsocModule.h ...... 59 A.6 WinsocModule.cpp ...... 62 A.7 RakNetModule.h ...... 88 A.8 RakNetModule.cpp ...... 90

B Modified RakNet Big Packet Test 97 B.1 BigPacketTest.cpp ...... 97

C Hardware List and Network settings 106

D Literature study 108

v vi Chapter 1

Introduction

1.1 Background

A common and popular feature for today’s video games is the ability to play together with players from across the world. Being able to play the same game, at the same time, with friends or strangers is the main selling point of many games. The games that support this feature stretch from turned based strategy games[1][2] to a fast paced shooter[3][4]. To make the experience enjoyable for the players, the game has to always feel responsive even though the data might have to travel from one side of the planet and back again. Depending on the game, the requirements for transport time and reliability of the data will vary. This is why it is important for the developer of a games networking system to know what can be done to optimize the game’s networking to best suit its requirements.

1.2 Problem Description

There are many variables that determine the total time it takes for one packet of data to be sent from one system to another. Some of the variables can not be interacted with and are therefore constants, such as the time it takes the data to physically travel from one device to another. There are also other variables that can be changed and optimized to make the total travel time faster. Determining the best combination of these variables is the key to making an effective and fast communication system for video games.

1.3 The Scope of the Thesis

For this paper, a literature study will be conducted using the ”Snowball” method described by Claes Wohlin in his paper ”Guidelines for Snowballing in Systematic Literature Studies and a Replication in Software Engineering”[5] to identify earlier works in the field that are relevant to this paper and the experiment. The results of the literature study can be found in Appendix D. The selected papers from the literature study will be further discussed in Chapter 2.

After studying the results of the literature study, three independent variables have been iden- tified to impact the Packet Delay and will, therefore, be the main focus for the experiment. The three variables are Transport Protocol(TP), Packet Size, and Network Configuration. These

1 variables will be discussed in more detail in Chapter 3. This paper will use a comparative analysis to compare different real combinations of these variables. Each combination will vary its Transport Protocol, Packet size used and Network Configuration to identify any changes to its Packet Delay and Throughput. The research goal of this analysis is to identify which combination would be best suited for given network requirements based on Packet Delay and Throughput. In this paper, there will be two test scenarios, one that will measure the Packet Delay, and one that will test the Throughput of the implementation.

The first scenario will have the combinations to only to send a single packet at a time and measure the one-way travel time of that packet. This is to determine the sending speed and potential differences in packet delay between Network Configurations. The second scenario will have the combinations send one gigabyte of data to measure the throughput of the combination. The experiment will be executed using a test bed where different combinations of the variables can be tested and data will be collected on Packet Delay, Bandwidth, Packet Loss, and CPU Work Load. More information will be provided in Chapter 4. Finally, the data will be presented in graphs in Chapter 5. The results will be analyzed in Chapter 6 and finally, a summarized answer to the research questions will be presented in Chapter 7.

1.4 Research Question

To summarize; there will be two research questions that this paper will try to answer.

1. What is the impact of different combinations of transport protocols and packet sizes on the packet delay and bandwidth?

2. How does the network configuration impact on the packet delay?

2 Chapter 2

Previous Work

In their book, “Performance Analysis of Computer Networks” [6], Matthew Sadiku and Sarhan Musa talk thoroughly about the techniques and performance measurements normally used to analyze network performance. They discuss the three performance evaluation techniques of a network, measurement, analytic modelling, and simulation and the pros and cons in different situations. They also describe the inner workings of different topologies for both LAN and WLAN which are the network configurations this paper will mainly focus on. The methods used in this paper will be based on the guidelines discussed in this book.

In the paper “TCP and UDP Performance over Wireless LAN” [7], by George Xylomenos and George Polyzos, a similar experiment to the one in this paper is performed. By doing a real implementation of both TCP and UDP while varying the packet size and processing power, the authors try to identify how the performance of the system changes depending on the variables. The goal of the journal is to identify performance problems in realistic conditions for UDP and TCP but does not try to compare the protocols against each other to determine the optimal choice in the given scenario. The experiment that will be performed in this paper will be similar to the experiment executed in the journal, but with some additional variables such as network configuration, and with the goal to compare the results against each other to identify the best combination of variables for each scenario.

There are also multiple papers that perform performance measurements with TCP and/or UDP, but not with real implementations [8, 9, 10, 11]. Many researchers seem to prefer to simulate their experiments using software such as “The Network Simulator (ns-2)”[12]. Using an established Simulation program such as NS2 for an experiment is in most cases both faster and more cost effective than to making a real implementation. It also avoids outside factors that might skew the results. This is also why a simulation is not always the best way to go. A simulation in most cases does not reflect reality since there is a lack of unexpected outer factors that would impact the final results. This is why in this paper the experiment will be based on a real implementation instead of running a simulation.

Based on the literature study conducted, there are no more papers related to this thesis. There are more papers that do conduct network measurements and comparisons like the papers mentioned earlier[8, 9, 10, 11], but the author decided there were not much credit to include more papers that were not directly related to this thesis.

3 Chapter 3

Theory

3.1 What impacts the problem

To determine what design decisions a developer has to take, the author has identified three independent variables that will have an effect on the Packet Delay. By doing a comparative analysis of different combinations of the variables, it will be possible to find the individual impact on the Packet Delay for each one of them. The variables that will be tested in this thesis are; Network Transport Protocol, Packet Size, and Network Configuration.

3.2 Network Configuration

Network Configuration is the network’s physical structure. This means how two computers are connected to each other, more often than not, by Ethernet cables, switches, and routers. With bigger networks such as the Internet, it is between these devices where most of the Packet Delay time is created. The time for a packet of data to traverse a network grows bigger the more connections and network devices it has to travel through. Each device adds further latency to the Packet Delay. This is because each device that the packet has to travel through, will have to read and redirect each packet that it handles. When the input is higher than the reading capabilities of the router, a buffer is created to store incoming packets while it reads the oldest packet in the buffer. In public networks where there may be thousands of users at the same time, the device buffer may get close to full and will, therefore, create a noticeable delay for incoming packet since it has to wait in the buffer to be processed. If a buffer is full when a packet arrives, the arriving packet will be discarded and lost forever[13]. This can create big problems for a system if it is not programmed to handle packet loss, and even if it handles the loss, it will create further delays. The redirection of the packet takes time as well. The device has to read the packet and extract the destination from it, checking its internal network map, and then redirecting the packet to the next device. The time it takes for a device to do this is not big[14], but it is close to a constant time that will be multiplied by the number of devices that the packet will traverse through. In this thesis, there will be four types of network configurations: 1-1 with Ethernet cable without any intermediate device which will serve as the baseline for the experiment, 1-1 with Ethernet cable with switch, 1-1 on a dedicated WIFI (only the two computers on it), and 1-1 on public WIFI (other computers on the WIFI).

4 3.3 Network Transport Protocols

Network Transport Protocol, or just simply Transport Protocol(TP)[15], is the description of how the given data should be packeted, sent, received, and handled if lost. Following will be a detailed description of the protocols that will be used for this thesis and how they be- have compared to each other. In this thesis, we will focus on the two most common TPs and two variations on them and how they impact the Packet Delay and the bandwidth of the sys- tem. The protocols used in this thesis are TCP, TCP(NoDelay), UDP, and UDP implemented with RakNet. All of them are well documented, thoroughly tested, and they are considered a standard for each of their fields. Therefore it is considered safe to use these protocols for the experiment.

TCP (Transmission control protocol)[16] is a reliable protocol that guarantees that the packets always arrives at their destination. This is done by adding an acknowledging system which requires the receiver of the packet to send an ack(acknowledge) packet to the sender to tell it that the packet has arrived. If the original sender does not receive an ack packet, it will assume that the sent packet was lost and will resend it. This method is reliable but slow since TCP also confirms in what order packets should arrive. So if a series of packet 1,2,3,4, and 5 is sent in that order and packet 1 is lost, the other packets will have to wait until packet 1 is resent and arrives before being processed. This slows down the communication a lot. TCP also have another way to prevent overflowing buffers. The congestion window and receive window of TCP creates congestion control which tries to avoid packet loss by throttling the number of packets sent each frame by different means. The sender uses the congestion windows to define how many packets that can be sent each frame, and when a successful send is completed it slightly increases its size. But when the sender detects packet loss, it halves the congestion window, assuming that it is because of a buffer got full. By halving the throughput, TCP hopes to let the buffer process the stacked packets in its buffer before trying to pressure it again with a higher number of packets. The receive window is used by the receiving system and announces for the sender how many bytes are still left in the receiver buffer. This helps the sender to know how many packets it can send before it would fill up the receiver buffer.

TCP(NO). The second protocol is the same TCP as in the first, but with one flag changed, NO DELAY. When this flag is used on initialization, Nagle’s algorithm[17] will be turned off. Nagle’s algorithm is used to take small packets and put them into a buffer until there was enough of data to fill a larger TCP packet. This way, the overhead was minimized for the cost of speed. By disabling Nagle’s algorithm in TCP, it sends small packet a lot faster which can be useful for games that require small and fast packets to function.

UDP. The third protocol is UDP (User Data Protocol)[18]. UDP is a protocol that focuses on sending the data packets as fast as possible without regards if they arrive at the destination or not. In contrast to TCP, UDP does not handle lost packages, but processes packages as they arrive and is therefore often used for games that do not care for the order that the data arrives in, but about what data is the most up-to-date.

RakNet. The fourth and final protocol is UDP implemented with the RakNet[19] library. RakNet is a high performance, cross platform, game network engine which is designed to reliably handle packet loss and congestion control. This will increase the reliability of the UDP protocol which should prove interesting for the experiment results.

5 3.4 Packet Size

Packet size is the size of the data packet. Each packet contains a header with a fixed size besides the data that will be transported. In some cases, it can be good to put different data in the same package to save the overhead of having multiple packets and headers and only send one larger packet instead of multiple small ones. The negative side of this is that one big packet will take up much space in the buffers which may create bigger packet loss if the buffer is not large enough to handle the incoming packets.

The theoretical max size for TCP and UDP are around 64 kB (TCP 65535 bytes[16] and UDP 65507 bytes[18]), but packets of this size are not commonly used. That is because of the MTU (Maximum Transmission Unit), which is the maximum size of data that can be sent at a time. By effect, this means that if data with a size larger than the MTU is passed from the to the network layer, the data will be fragmented into smaller packages that are provided with the IP header with the final destination address. These packages will be the ones to be sent over the physical link. In this paper, the MTU size used for the experiment was 1500 bytes for all scenarios.

6 Chapter 4

Method

4.1 Method Description

There are three independent variables in that will be tested in this experiment: transport protocol, packet size, and the network configuration between the processes. The transport protocol variable will be tested with four values: UDP, TCP, TCP with the NO DELAY flag active which disables Nagle’s algorithm, and UDP implemented with RakNet. The packet size will range between set values that will be the same for every combination of Transport Protocol and connection type. The final packet size is determined by the network interface MTU value as mentioned in Chapter 3 Theory. The MTU value will be set through windows command console (cmd) and will be covered in detail later in this chapter under the Execution Section. There will be four types of network configurations: 1-1 with Ethernet cable without switch which will serve as the baseline for the experiment, 1-1 with Ethernet cable with a switch, 1-1 on a dedicated WIFI (only the two computers on it), and 1-1 on public WIFI (other computers on the WIFI).

There will be two different scenarios that will test the different combinations of variables. The first scenario will measure the travel time of a single packet. Here, the packet sizes will be identical for all the protocols and network configurations. This will determine what combination creates the fastest single packet transport time. In the second scenario, the system will have to send a large amount of data (1GB) over the network. This is to measure the bandwidth used and the reliability of the different transport protocols. To transport 1 GB of data, the packet size for TCP, TCP(NO), and UDP will use one set of packet sizes while RakNet will use another set. This is because RakNet handles large packet transfers differently and sends larger ”segments” at a time instead of individual packages. The RakNet part of the experiment will be based on their own example project, ”Large Packets” and the modified file can be found in appendix B. Even though the packet sizes will differ, the purpose of the second scenario is to determine the effective bandwidth used, but it is worth noting the difference in the handling of the data. In none of the scenarios will data validation be a factor. For the experiment, the payload of the packet will be filled with throwaway values and will not be processed by the receiving system. This is to save processing power and keep the throughput as fast and consistent as possible.

A program will be implemented to give full control over all the variables in the experiment. The program will give the user the options to choose the transport protocol, the amount of data to send, packet size, the IP address to connect to, and if the program will send or receive data. The source code of the program can be found in Appendix A. The collection of data will

7 be handled by windows own Performance Monitor tool which allows the user to create a ”user defined data collector set” where the system’s performance data can be collected.

The environment that the experiment will be executed in will be two identical computers with Windows 10 operating systems. Both computers will run an instance of the program, one set to send data and the other to receive data. This way, full control can be had over both the sending and receiving of packets and can, therefore, be measured reliably. This means that the sending and receiving sides will not perform any other computation other than sending and receiving data. This is to isolate the impact of each variable on the packet delay (PD) as possible. To study the basic latencies that are introduced by additional network devices such as switches and routers, the experiment will first start with a simple one to one Ethernet cable connection. Then by adding more devices that the data has to go through, each device’s latency can be determined.

By testing all different combinations of these variables and measuring the Packet Delay and the bandwidth, and then plotting the results to graphs will grant the answer to the first research question. The connection type of 1-1 with Ethernet cable without switch will serve as the baseline for the PD since the effect of external disturbances will be minimal. By comparing the baseline with the other connection types, the impact of the connection can be deducted and answer research question two.

The experiment will only study one peer to one peer communication. This is to try to isolate the impact of the variables as much as possible in each scenario. Therefore, the result of this experiment will suit one to one connections more, but the experiment could still be done with other network configurations such as a server-client setup.

Since there will be a risk for packet loss for UDP in combination with some of the network configuration options, the loss of data statistics will also be collected and presented together with the bandwidth in the analysis.

4.2 Execution

Hardware Setup: This part of the paper is a step-by-step tutorial how the experiment was performed. The hardware used in the experiment can be found in Appendix C. Set up two computers with Windows 10 operating system and install the network measuring program (In this paper the computers had the same specifications).Chose which computer will be the sender and which will be the receiver and then start the network measuring program with the following parameters on the corresponding computer:

• Sender: -s -*protocol* -ip *ip-address of receiver* -p *number of iterations*

• Receiver: -r -*protocol* -p *number of iterations*

The Sender has three parameters. The ”-s” is to tell the program that it will be the sender and will therefore also require the ”-ip” parameter to set the ip-address it will connect to. The Receiver uses ”-r” instead of ”-s” to set itself up as the Receiver. Both programs will have the same protocol parameter which will define what transport protocol

8 will be used by the program. There are four options: ”-u”(UDP), ”-t”(TCP), ”-tn”(TCP(NO)), and ”-rn” (RakNet). The last parameter is in what mode the program will run in. Both the programs will have to have the same transport protocols or the programs will fail. The ”-p” parameter is to set the program in ”ping mode” which means that it will measure the travel time of a single packet. Entering ”-ps” instead of ”-p” will put the program into throughput mode which is used for the second scenario. The ”-ps” parameter will be followed by the size of the packets for the throughput test. The MTU of both computers were checked before the experiment started so that it was set to the standard size 1500 bytes for Ethernet communication. This means that if a packet larger than 1500 bytes is trying to be sent, it will be fragmented into smaller packages as discussed in Chapter 3: Theory. When all combinations packet size and protocol has been tested on one network configuration, it is time to switch over to the next one and redo the test. In this experiment four network configurations were used, 1-1 with Ethernet cable, 1-1 with Ethernet cable with a switch, 1-1 on a dedicated WIFI (only the two computers on it), and 1-1 on public WIFI (other computers on the WIFI).

Packet Travel Test: To perform the packet travel test, all that is needed is to enter the correct parameters for both the Sender and Receiver. The Receiver has to be started before the Sender for it to connect correctly. After that, the program will measure the speed of four different sized packets. The sizes are 4, 512, 1024, 1500, and 2048 bytes. This is to identify if there is any difference in speed when the packet size is smaller or larger than the MTU of 1500 bytes. The one-way travel time is calculated by using a variation of Cristian’s algorithm described in Flaviu Cristian’s paper (Probabilistic clock synchronization)[20] which is to take the total travel time and divide it by two, assuming that the travel time is the same both ways. In this paper, the experiment also used four different amounts of iterations to see if there would be any notable differences in speed and in UDP case, packet loss. Data was collected for 100, 500, 1000, and 100.000 iterations. The time will be measured in nanoseconds as the overhead this thesis is trying to examine is very fast. By using nanoseconds it will be possible to identify even smaller changes to the total travel time. When one test is completed, switch the topology and redo the test until all protocols, packet sizes, and topologies have been measured. The results will be printed into text files next to the executable file.

Throughput Test for TCP, TCP(NO), and UDP This section is only for the protocols TCP, TCP(NO), and UDP. This is because RakNet uses another program to send large packages and will therefore have its own section below this one.

In the throughput test, it is needed to collect some more data than in the packet Travel test. To do this, open the ”Performance Monitor” program provided by Windows 10 and create a new ”User defined Data Collector Set” and add the following Performance Counters to the set:

• NetworkAdapter/Bytes sent per second

• NetworkAdapter/Packets sent per Second

• NetworkAdapter/Current Bandwidth

• Processor/User Time in percent

9 The coloured part of the Counter names may vary depending on the computer and what parts it uses. This allows one to collect information on how the network adapter and CPU work while the program is transferring the 1GB of data between the two computers. A user would want to set a directory where the resulting data file would be saved. The parameters are similar to those in the first test. The only real difference is the ”-p” parameter and should be changed to ”-ps” followed by the size of the packets that should be sent. In the experiment, there were three sizes used, 10240, 30720, and 61440 bytes. The difference in size is trying to create overhead by forcing the transport protocol to fragment the packages into smaller packages to fit the MTU of 1500 bytes. Unlike the Packet Travel Test, there will only be one iteration of each combination of variables since the transfer times will allow the Data Collector Set to collect more than enough data to draw conclusions from. Before starting the program start the Data Collector Set and then the program. When the program has successfully sent 1GB of data, the user will have to stop the Data Collector Set manually. The result files from the program will be next to the executable like in the first test, while the Data Collector Set result file will be at the predefined location.

Throughput Test for RakNet As mentioned above, RakNet sends large data packages a bit differently than the author’s program. Instead of letting the user send individual packets of a certain size, it defines large ”segments” that is then split up in smaller packages of that the API determines suitable. In this experiment, the RakNet example project was used and modified to send 1GB of data. The modified RakNet project can be found in Appendix B. The author chose the segment sizes of 40 MB (41943040 bytes), 80 MB (83886080 bytes), and 160 MB(167772160 bytes). The sizes were chosen to see if the RakNet API would handle the sizes differently. The example project also starts it connection differently from the author’s program. The ”Sender” only initialize the communication but it is the ”Receiver” that send the segments back to the ”Sender”. this means that to collect the throughput data with the Data Collector Set, it will have to be run on the ”Receiver” computer instead of the ”Sender” as in the other tests. Even though the way that the data is sent and handled, the collected data will still be relevant to compare the differences in throughput against the other transport protocols. As the experiment will take much longer time than the one-way travel time experiment, the time unit will be changed from nanoseconds to milliseconds.

4.3 Expected Results

The result will be presented in a series of graphs. There will be one graph for each type of implementation and the result will be based on the data collected in the two test scenarios the implementations will be put through. This will give a good and easy overview of the speed of each combination of transport protocol and packet size for every connection type. An informed answer will be obtained how the different implementation behaves individual and compared to each other. Other outcomes for the experiment could be that the results are very similar to each other and the author can not deduct any noteworthy impact on the Packet Delay or throughput in any combination of independent variables. In this case, the experiment will have to be revised to find another method of measuring and/or and identify new independent variables. The paper “TCP and UDP Performance over Wireless LAN” [7], that was discussed earlier in Chapter 2, shows that changing the variables should lead to different results for both in single packet speed and throughput which is in line with the author’s expectations.

10 Chapter 5

Result

In this chapter, all the data collected will be displayed in graphs. The results will be divided into two categories, Delay Results which is the data collected on the one-way travel time of a single packet, and Throughput Results which will show the throughput of the connection while transferring one gigabyte of data.

11 5.1 Delay Results

As mentioned above, this section will show the average one-way travel time for a single packet between the two systems. The packets were sent one by one while the travel time is calculated for each one. The average time will be calculated for 100, 500, 1000, and 100.000 iterations. In this all observations and analysis will be based on the 100.000 iteration measurement since it is based on the largest amount of data-points. Data was collected for smaller number of iterations as a compliment and to identify if there was an increase or decrease in packet sending speed when more packets where sent. The black vertical line at the top of each bar is a visualization of the standard deviation of time for all the packets sent. This is to show the how the different packet times differ throughout the experiment.

5.1.1 Ethernet

The result for the Delay test for the Ethernet network configuration. Here there are no inter- mediate devices between the computers since they are directly connected by a 1Gbit Ethernet cable.

Figure 5.1: Ethenet TCP Delay Results

12 Figure 5.2: Ethenet TCP(N) Delay Results

Figure 5.3: Ethenet RakNet Delay Results

13 Figure 5.4: Ethenet UDP Delay Results

14 5.1.2 Switch

The result for the Delay test with a switch between the two computers. This adds an additional device that has to handle the data packets before they arrive at their destination. With added overhead, there should be an increase in travel time for the packets which hopefully can be seen in the graphs.

Figure 5.5: Switch TCP Delay Results

15 Figure 5.6: Switch TCP(N) Delay Results

Figure 5.7: Switch RakNet Delay Results

16 Figure 5.8: Switch UDP Delay Results

17 5.1.3 Private Wifi

The result for the Delay test on a private wifi connection. By introducing a not as fast of a connection as a physical one, the packets one-way travel speed should be a lot slower. There were only the two computers that executed the experiment on the network to avoid network traffic that could interrupt the test.

Figure 5.9: Private wifi TCP Delay Results

18 Figure 5.10: Private wifi TCP(N) Delay Results

Figure 5.11: Private wifi RakNet Delay Results

19 Figure 5.12: Private wifi UDP Delay Results

20 5.1.4 Public Wifi

The result for the Delay test on a public wifi connection. With he introduction of public network traffic, it should be expected that this network configuration should prove to be the slowest. The increase in traffic should fill up buffers and increase the time the packets have to wait before being processed.

Figure 5.13: Public wifi TCP Delay Results

21 Figure 5.14: Public wifi TCP(N) Delay Results

Figure 5.15: Public wifi RakNet Delay Results

22 Figure 5.16: Public wifi UDP Delay Results

23 5.2 Throughput Results

The throughput test will focus on the throughput of the system while transferring one gigabyte of data. The size of the data packets that were sent varied between 10240, 30720, and 61440 bytes with the exception for RakNet as discussed in ”Chapter 4”. This way it should be possible to identify how the throughput varies depending on the size and network configuration and which combination is superior in what scenario.

5.2.1 Ethernet

The result for the Throughput test on an Ethernet connection. The physical connection should be the fastest and most stable connection out of all the other network configurations. The speed is only limited by the cables transfer speed and the receivers reading speed.

Figure 5.17: Ethernet TCP Throughput Results

24 Figure 5.18: Ethernet TCP(N) Throughput Results

Figure 5.19: Ethernet RakNet Throughput Results

25 Figure 5.20: Ethernet UDP Throughput Results

26 5.2.2 Switch

The result for the Throughput test with a switch between the systems. Now with more data traffic on the network, there is a higher risk for buffer overflow which would result in packet loss and longer transfer times. The size of the packets might have a big impact in how the buffers will handle them selfs and the resulting throughput.

Figure 5.21: Switch TCP Throughput Results

27 Figure 5.22: Switch TCP(N) Throughput Results

Figure 5.23: Switch RakNet Throughput Results

28 Figure 5.24: Switch UDP Throughput Results

29 5.2.3 Private wifi

The result for the Throughput test where the systems are connected over a private wifi with no other traffic. With the higher output of the sender, the router buffers will have a harder time to process the incoming data packets.

Figure 5.25: Private wifi TCP Throughput Results

30 Figure 5.26: Private wifi TCP(N) Throughput Results

Figure 5.27: Private wifi RakNet Throughput Results

31 Figure 5.28: Private wifi UDP Throughput Results

32 5.2.4 Public Wifi

The result for the Throughput test where the systems are connected to a public wifi where other network traffic will be present. As mentioned before, the increase of traffic on the network will result in more packet loss and that, in turn, will lead to lower throughput.

Figure 5.29: Public wifi TCP Throughput Results

33 Figure 5.30: Public wifi TCP(N) Throughput Results

Figure 5.31: Public wifi RakNet Throughput Results

34 Chapter 6

Analysis

6.1 Packet Travel Time Test

Ethernet: With a Direct Ethernet cable connection between the two systems, the fastest protocols were TCP (Fig. 5.1) and TCP(N)(Fig. 5.2) as they had close to identical one-way travel times for all packet sizes used. No clear difference in speed when packets larger than the MTU was used so direct impact of packet fragmenting. The second fastest was UDP (Fig. 5.4) with only a couple of thousands of nanoseconds slower than TCP. And the slowest was the RakNet (Fig. 5.3) implementation with units of tens of thousands nano-seconds slower than UDP for all packet sizes.

All of the protocols had very low delay variation which is most likely because the internal buffers of the systems never got filled up since only a single packet was handled at a time.

Switch: When a Switch is introduced between the two systems and connected by Ethernet cables, there is no clear fastest protocol. TCP (Fig. 5.5) and TCP(N) (Fig. 5.6) are faster than UDP (Fig. 5.8) and RakNet (Fig. 5.7) for 4 and 512 bytes packets but TCP takes a great drop in speed for 1024 and 1500. UDP and Raknet, on the other hand, seems to have much more stable speed throughout all packet sizes even if they are slower in most cases compared to TCP. The general decrease in speed for all protocols is because of the introduction of the switch. Since the packet now has to queue in another buffer and be read again before being sent on to the intended system. The Switch seems to add 20.000 - 30.000 nanoseconds (0.02-0.03 milliseconds) delay for the one-way trip.

The reason for TCP’s drop in speed for 1024 and 1500 bytes packets might be caused by fragmenting overhead or Nagle’s algorithm waiting for more data before sending the packet. Nagle’s algorithm seems unlikely since it would already be active in all the other packet sizes. Fragmenting also seems unrealistic since the other protocols did not see a similar decrease in speed. Also, the speed is increased back to normal for TCP and TCP(N) for the 2048 byte packets. One should expect the fragmenting to happen to the 1500 and 2048 byte packets since the MTU was set to 1500 bytes. The only logical thing left that could impact the travel time of the packet is other programs interfered with the experiment. Since the experiment was executed on computers with a Windows operating systems, there are background processes that might have interfered.

35 Wifi Private: The two systems are connected with a private wireless network with no other devices connected to it. Relatively even between all protocols even though there are some areas for all protocols that are irregular. RakNet (Fig. 5.11 ) have a really fast time for 4 bytes packet with 750.000 ns (0.75 ms) but then goes back up to 1.100.000 - 1.200.000 ns (1.1-1.2 ms) for all other packet sizes. TCP (Fig. 5.9) has a similar oddity with the 512-byte packet at 1.000.000 ns (1.1 ms) compared to the other packets of around 1.200.000 ns (1.2 ms). TCP(N) (Fig. 5.10) became slower for 1500 and 2048 byte packets with around 100.000 ns compared to the earlier packets and finally UDP (Fig. 5.12) becomes faster at the 512 and 1024 bytes packets with around 200.000-300.000 ns (0.02-0.03 ms). But the consistent fastest protocol is UDP followed by RakNet with TCP and TCP(N) in the last place. The packet loss for UDP was lower than 0.01% of 100.000 packets which is only ten packets lost which are a minuscule loss overall. With the data not travelling through a cable anymore, a further delay has been added across the board and brings the travel time consistently into the millisecond time range. Compared to the earlier Network Configurations, now with wireless networks, several outside variables have been introduced into the calculation. A major factor is that the connection between computer and router is not a constant. The connection will be weaker and stronger over the course of the experiment and will impact the one-way delay of a packet. The oddities noticed above are probably the result of varying connectivity of the wireless network. The variables impacting earlier measurements still apply but are harder to identify when the connectivity plays a much bigger factor into the final travel time.

Wifi Public: For the final Network Configuration, the systems were connected using BTH’s public student wireless network Eduroam. On this network, there are a lot of nodes to go through and different users competing for access at the same time. RakNet (Fig. 5.15) was clearly the fastest of all the protocols in both speed and consistency. TCP (Fig. 5.13) and TCP(N) (Fig. 5.14) had similar speeds for packets of the same size but the speed between different packet sizes varied with around 200.000 ns (0.02 ms). UDP (Fig. 5.16 ) which is the absolute slowest of the four protocols are similar to RakNet in that they both are very consistent in their one-way travel time. For UDP, the loss rate was only 0.000014% which is only seven packets lost for all packet sizes combined.

Except for UDP, the overall travel times seem to have gone down which would mean a couple of things. Eduroam’s connection is much more stable than the router used for private wifi, and despite having more traffic on the network, it still delivers the packets faster. This can be because of the processing power of the Eduroam system and be further helped if there were not a lot of traffic at the time of the experiment. This could also be the reason why UDP is so much slower than the other Protocols. The UDP part of the experiment might have been executed during a time of high traffic on the network. Authors note; The experiments were done on different days but mostly on the same time of the day to have as consistent traffic as possible. The experiments were performed between 10 am to 3 pm, which is the time where most students are active at BTH campus. This is to have as much network traffic as possible to differ the public wifi connection from the private connection.

36 6.2 Throughput Test

Ethernet: RakNet (Fig. 5.19) as by far the highest throughput of all the implemented protocols even if the throughput varies from time to time. UDP (Fig. 5.20) has the second largest throughput and the size of the individual packet does not seem to impact the throughput in any meaningful way. For TCP (Fig. 5.17) and TCP(N) (Fig. 5.18) on the other hand, their throughput speed is greatly impacted by the size of the packets sent. It also seems like Nagle’s algorithm can clearly be seen as having an impact on the consistency of the throughput. While TCP(N) has a relatively even throughput, TCP has a very uneven throughput. This is because the protocol waits for more data before sending a larger packet and that can be seen as the larger steps between the higher tops on the graph. Overall, for TCP and TCP(N) it seems to greatly gain throughput by increasing the packet size while UDP only gets a marginal increase. This is probably because of the way the packets are packeted and sent in UDP compared to TCP.

The reason why RakNet is so much faster than the other protocols is probably because it is an actual commercial product that has been developed, optimized, and thoroughly tested by professionals while the implementations for TCP, TCP(N), and UDP are implemented by the author of this paper and is therefore not as thoroughly tested and optimized.

Switch: No real change can been seen for the RakNet (Fig. 5.23) and UDP (Fig. 5.24) implementation from the earlier Ethernet test. It seems like TCP(N)’s (Fig. 5.22) throughput varies much more than before. This can be because of the switch buffers getting filled up by all the data and communication packets TCP uses, and since more packets are sent since Nagle’s algorithm is turned off, more traffic is created and create longer queues and possible packet loss. There is also an increase in throughput for regular TCP with the packet size of 10240 bytes(Fig. 5.21) but no explanation was found to why this happens.

Wifi Private: UDP (Fig. 5.28) has overtaken RakNet (Fig. 5.27) in throughput for certain packet sizes. When UDP send packets of 10240 and 30720 bytes, it is faster or as fast as RakNet, but when sending 61440 bytes packets, the packet loss rate increased to 240%. This means that for every packet that arrived at its destination 2,4 packets never arrived and had to be re-sent. It is unexpected that this first occurs when the packets get larger than 30720 bytes, but this might be caused by the router buffers getting filled up and then dropping incoming packets and since there is no ”back-off” method in place for the UDP implementation in keeps sending packets that continue to get dropped.

For TCP (Fig. 5.25) and TCP(N) (Fig. 5.26) there seems to be a similar problem. The throughput is increased from 10240 bytes packets to 30720 bytes, but when larger packets are sent, throughput drops. The reason that TCP(N) gets even lower throughput can already be explained by the extra packets created by not packeting smaller packets together and therefore creating more traffic to overflow the router’s buffers. The spikes in the TCP and TCP(N) throughput look like the effect of the congestion window halving the throughput when packet loss is detected, and packet size seems to have a large impact on the packet loss. The 10240-byte packets have relatively small spikes compare to the 61440-byte packets. Smaller packets seem to have lower drop rate than the larger packets.

37 Wifi Public: For this part, data could not be collected at all for UDP since the drop rate was so high that the program never succeeds in transferring a whole Gigabyte of data to the destination. For the remaining protocols, the throughput dropped drastically but RakNet (Fig. 5.27) still has the highest. But for some reason, the sum of RakNets total throughput in this experiment have exceeded the 1GB of data that should have been sent. The total amount of data sent is close to 2 GB. The reason for this is unknown but it is most probable that there is another process running in the background that disturbed the measurement of data sent since there is no packet loss for 41943040 and 83886080 bytes segments and only a single packet for the 167772160 bytes segment.

Packet size seems to have much lesser or no impact at all on the throughput for TCP (Fig. 5.25) and TCP(N) (Fig. 5.26). It is also hard to identify the impact of Nagle’s algorithm and the congestion window seems to behave similarly for both TCP and TCP(N) which would imply similar packet loss. It is unknown why the drop rate for UDP got so high but it could probably be explained by two factors. It could be high network traffic at the time of the experiments. The author also suspects that BTH might have an anti-DDOS system in place, and by sending a lot of UDP packets through the system might have triggered it and stopped further packets.

38 Chapter 7

Conclusion

7.1 Summary

During this experiment, the protocols have been compared against each other in two categories in an effort to determine which one of them is best suited to what kind of a scenario. The categories are Single Packet Travel Time and Throughput.

Ethernet A simple 1-1 connection with an Ethernet cable is a high bandwidth and low latency and can, therefore, be suitable for any of the tested protocols. That said, TCP and TCP(N) have the fastest one way trip of a packet while UDP has the highest Throughput. There are also some additional concerns to consider before choosing which protocol to use. Even though the TCP protocols have the fastest one-way travel time compared to UDP, TCP creates additional traffic in the form of ACK packet that is not really needed since there is no packet loss over LAN. In that way UDP is superior since it only sends the data given to it and nothing else, keeping the amount of data sent to a minimum. TCP(N) should also increase the effectiveness of sending small packages at a high frequency since it will not wait for other packages or a timeout before sending the packet. The downside with this is that it will create more overhead and network traffic because of the additional ACK packets used.

Switch As for the Ethernet, TCP and TCP(N) has the fastest one-way travel time and UDP the highest throughput. The travel time of packets is still very fast and all the protocols are usable. With the introduction of the switch buffer, there is a greater emphasis on keeping the amount of packet on the network to a minimum to avoid filling up the switch buffer. In this experiment, there were no instances of packet loss for UDP, but there is the possibility that there could occur packet loss. For the same reason, TCP(N) is not as optimal as regular TCP, since the extra ACK packets created increases the risks for packet loss.

Wifi Private With the introduction of wifi network connection, UDP has the fastest one-way travel time for a packet. The main reason for this is that there is no extra synchronization as for TCP, TCP(N), and RakNEt, but this may be a big problem if the user absolutely requires the specific data sent or the order of the packets matter. UDP is good for applications that update at a high frequency, such as First Person Shooters. If reliability is a concern, TCP, TCP(N), and RakNet are the way to go since they implement synchronized communication between the systems. This can be seen when moving on to the throughput. UDP has the highest throughput but still is

39 slower than RakNet to transfer 1Gb of data. Because of the packet loss and resending of data creates so much extra overhead for UDP that RakNet with it lower throughput still manages to send the data faster thanks to its synchronization system.

Wifi Public RakNet has both the fastest throughput and one-way packet travel time. TCP and TCP(N) are sharing second place, while UDP has the slowest one-way travel time and the throughput could not be measured because of the massive packet loss. RakNet seems to be the most reliable of the protocols when it comes down to wireless networks with a lot of traffic. One reason why RakNet performs well compared to the other protocols is that it is a thoroughly developed and tested network engine for commercial use. It is no surprise that it would perform well in public networks that it was developed for. This is not to say that the other protocols are not options, but to implement them in an effective way that can compete with RakNet might be problematic for newer developers.

7.2 Future Work

There are several improvements to the experiment that could be done, and there are also a couple of new areas that would be interesting to explore in the future. For improvements, it would be interesting to make and use more thoroughly tested and optimized implementations of all the variable combinations to create a system that is closer to real applications. This would greatly increase the validation of the measurements and more weight to the conclusion. It would also be interesting to do the experiments with sensitive data where the content of the packet matters. In the experiment performed here, the packets only contained throw away data that were never read by the receiver. To measure the how packet corruption impacts the different implementations is an important part of some networks systems and could, therefore, prove useful.

40 Bibliography

[1] Age of Empires 2, Developed by Ensembly Studios, Published by Microsoft 1999 [2] Starcraft 2, Developed and Published by Blizzard Entertainment 2003, [3] Quake, Developed by id Software, Published by GT Interactive 1996 [4] Overwatch, Developed and Published by Blizzard Entertainment 2016, [5] Cleas Wholin, Guidelines for snowballing in systematic literature studies and a replication in software engineering, EASE 14, Proceedings of the 18th International Conference on Evaluation and Assessment in Software Engineering, ACM New York, NY, USA 2014. 2014. [6] Sadiku, M. and Musa, S, Performance Analysis of Computer Networks, Springer Interna- tional Publishing., 1st Edition, 2013. [7] Xylomenos.G, Polyzos. G, TCP and UDP Performance over Wireless LAN, IEEE Press Piscataway, NJ, USA, Vol 39 Issue 4, 2001. [8] Sang-Hee Lee, Hong-Gu Ahn, Jae-Sung Lim, Sung Kim, Sang-Yun Lee, and Myung-Sung Lee, Performance Comparision between TCP-Reno and Freeze-Snoop TCP/SACK over cdma2000 Network Environments, Springer, Berlin, Heidelberg, Vol 2720, pages 462-470, 2003. [9] Shumin Xu, Yatao Yang, Protocols simulation and performance analysis in wireless net- work based on NS2, IEEE, ICMT 2011, Article number 6003076, Pages 638-641, 2011. [10] Kamal,J.M.M, Hasan,M.s, Carrington,A.L, Yu,H, Lessons learned from real MANET ex- periments and simulation-based evaluation of UDP and TCP, IEEE, ICCIT 2010, Article number 5723910, Pages 511-515, 2010. [11] Phil Karn. and Craig Patridge, Improving Round-Trip Time Estimates in Reliable Trans- port Protocols, ACM New York, NY, USA 1988, COMMACM SIGCOMM, 1987. 1987. [12] The Network Simulator - ns-2 [Online], Available at: http://nsnam.sourceforge.net/wiki/index.php/User_Information [Accessed 1 Sep. 2017]

41 [13] Tools.ietf.org. (2017).RFC 970 - On Packet Switches With Infinite Storage [Online], Available at: ://tools.ietf.org/html/rfc970 [Accessed 10 Sep. 2017].

[14] Priscilla. Oppenheimer, Top-Down Network Design, Cisco Press, Networking Technology 2004,(p.226), 2004

[15] Erg.abdn.ac.uk.(2017).Transport Layer Protocol [Online], Available at: http://www.erg.abdn.ac.uk/users/gorry/course/inet-pages/transport.html [Accessed 8 Apr. 2017].

[16] Tools.ietf.org. (2017).RFC 793 - Transmission Control Protocol [Online], Available at: https://tools.ietf.org/html/rfc793 [Accessed 8 Apr. 2017].

[17] Tools.ietf.org. (2017).RFC 896 - Congestion Control in IP/TCP Internetworks [Online], Available at: https://tools.ietf.org/html/rfc896 [Accessed 8 Apr. 2017].

[18] Tools.ietf.org. (2017).RFC 768 - [Online], Available at: https://tools.ietf.org/html/rfc768 [Accessed 8 Apr. 2017].

[19] Jenkinssoftware.com. (2017).RakNet - Multiplayer game network engine [Online], Available at: http://www.jenkinssoftware.com/ [Accessed 11 Apr. 2017].

[20] Flaviu Cristian, Probabilistic clock synchronization, IBM Almaden Research Center, San Jose, USA, Distributed computing, 1989 - Springer. 1989.

42 Appendix A

Bachelor Networking

Online Github Project: https://github.com/TobbetheStalker/BachelorNetworking

A.1 main.cpp

#include "WinsocModule.h" #include "RakNetModule.h" #include

//Raknet #include "MessageIdentifiers.h" #include "RakPeerInterface.h" #include "RakNetTypes.h" #include "MessageIdentifiers.h" #include "BitStream.h" #include "GetTime.h" #include "RakNetStatistics.h"

#pragma warning(disable:4789) #pragma comment(lib, "pdh.lib")

CONST LPCSTR COUNTER_PATH = "\\Network Interface(Realtek PCI GBE Family Controller)\\Bytes Sent/sec"; //"\\Processor(0)\\% Processor Time"; CONST ULONG SAMPLE_INTERVAL_MS = 1000; Protocol p = Protocol::NONE; std::string filename = "log"; char* ip = ""; bool isSender = false; bool ping = false; int pingIterations = 0; int packetSize = 0; #define BIG_PACKET_SIZE 83296256

43 bool SetParam(int argc, char* argv[]) { for (int i = 1; i < argc; i++) {

std::string arg = (std::string)argv[i];

if (arg == "-s") //Sender { // It is the sender who will record the time it takes isSender = true; } else if (arg == "-r") //Reciver { isSender = false; } else if (arg == "-t") //TCP { if (p == Protocol::NONE) { p = Protocol::TCP; } else { printf("Protocol has already been set"); return 0; } } else if (arg == "-tn") //TCP no delay { if (p == Protocol::NONE) { p = Protocol::TCP_WITH_NODELAY; } else { printf("Protocol has already been set"); return 0; } } else if (arg == "-u") //UDP { if (p == Protocol::NONE) { p = Protocol::UDP; } else { printf("Protocol has already been set"); return 0;

44 } } else if (arg == "-rn") //RakNet { if (p == Protocol::NONE) { p = Protocol::RAKNET; } else { printf("Protocol has already been set"); return 0; } } else if (arg == "-ip") //IP { // We will assume people will provide an ip address and nothing else

if (i + 1 < argc) //Check so this is not the final parameter { ip = argv[i+1]; //Read the next parameter into ip } else { printf("-ip needs to be followed by an ip address"); return 0; } } else if (arg == "-ln") //log name { if (i + 1 < argc) //Check so this is not the final parameter { filename = argv[i+1]; //Read the next parameter into ip filename.append(".txt"); } else { printf("-ln needs to be followed by the filename"); return 0; } } else if (arg == "-p") { if (i + 1 < argc) //Check so this is not the final parameter { pingIterations = std::stoi(argv[i + 1]); } else { printf("-p needs to be followed by number of iterations for the ping"); return 0;

45 }

ping = true; } else if (arg == "-ps") //Packet size { if (i + 1 < argc) //Check so this is not the final parameter { packetSize = std::stoi(argv[i + 1]); } else { printf("-ps needs to be followed by the selected packet size"); return 0; } } }

/* Final check to see if the crucial parameters has been set to valid values */

if (p == Protocol::NONE && ip == "") { return 0; }

return 1; } int main(int argc, char *argv[]) { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); bool run = true; bool conrq = false; bool calcDelay = false; int avgDelayNS = 0; int timeMS = 0; int totalTimeNS = 0; int timetotal = 0; int high = -1; int lowest = 999999999; int iterations = 1; std::ofstream file;

if (SetParam(argc, argv)) { WinsocModule wsModule; RakNetModule rnModule;

46 if (p != Protocol::RAKNET) //Winsoc { #pragma region wsModule.Initialize(p, isSender);

if (p == Protocol::TCP || p == Protocol::TCP_WITH_NODELAY) {

if (isSender) //Is set to be the sender {

wsModule.TCP_Connect(ip);

//Wait for connection, not really needed since TCP blocks until connection while (wsModule.GetIsConnected() != true) { wsModule.Update(); }

if (ping == true) //Calculate delay { std::string filename = ""; for (int i = 1; i < argc; i++) { filename.append(argv[i]); filename.append(""); } std::ostringstream os; os << pingIterations; file.open("../Logs/" + filename + "" + os.str() + ".tsv"); file << filename << "\n"; file << "Nummber of Iterations: " << pingIterations << "\n"; //Take avg delay of the connection for (int i = 0; i < 5; i++) { switch (i) { case 0: file << "4 bytes:\n"; avgDelayNS = wsModule.Calculate_AVG_Delay(4, pingIterations); break; case 1: file << "512 bytes:\n"; avgDelayNS = wsModule.Calculate_AVG_Delay(512, pingIterations); break; case 2: file << "1024 bytes:\n";

47 avgDelayNS = wsModule.Calculate_AVG_Delay(1024, pingIterations); break; case 3: file << "1500 bytes:\n"; avgDelayNS = wsModule.Calculate_AVG_Delay(1500, pingIterations); break; case 4: file << "2048 bytes:\n"; avgDelayNS = wsModule.Calculate_AVG_Delay(2048, pingIterations); break; }

printf("Average Delay: %d ns, ", avgDelayNS); printf("Highest Delay: %d ns, ", wsModule.GetHighest()); printf("Lowest Delay: %d ns \n", wsModule.GetLowest());

file << "AvrageDelay (ns) HighestDelay (ns) LowestDelay (ns)\n"; file << avgDelayNS << "" << wsModule.GetHighest() << "" << wsModule.GetLowest() << "\n"; file << "\n"; } file.close(); } else //Time data {

for (int i = 0; i < iterations; i++) { //Send data timeMS = wsModule.TCP_Send_Data(packetSize);

timetotal += timeMS; if (timeMS > high) { high = timeMS; }

if (timeMS < lowest) { lowest = timeMS; } } printf("Average time: %d, Highest Time: %d, Lowest Time: %d\n", timetotal / iterations, high, lowest);

std::string filename = ""; for (int i = 1; i < argc; i++) {

48 filename.append(argv[i]); filename.append(""); }

file.open("../Logs/" + filename + ".tsv"); file << filename << "\n"; file << "Packet Size: " << packetSize << " B\n"; file << "AverageTime (ms) HighestTime (ms) LowestTime (ms)\n"; file << timetotal / iterations << "" << high << "" << lowest << "\n"; file.close(); }

} else //Is set to be reciver { while (wsModule.GetIsConnected() != true) { wsModule.Update();

}

if (ping == true) { while(true) wsModule.TCP_Update(); //Only need to update } else { while (true) wsModule.TCP_WaitForData(); //Only need to update }

}

} else //UDP { if (isSender) //Is set to be the sender { if (ping == true) //Calculate delay { std::string filename = ""; for (int i = 1; i < argc; i++) { filename.append(argv[i]); filename.append(""); } std::ostringstream os; os << pingIterations; file.open("../Logs/" + filename + "" + os.str() + ".tsv");

49 file << filename << "\n"; file << "Nummber of Iterations: " << pingIterations << "\n"; //Take avg delay of the connection for (int i = 0; i < 5; i++) { switch(i) { case 0: file << "4 bytes:\n"; avgDelayNS = wsModule.Calculate_AVG_Delay(ip, 4, pingIterations); break; case 1: file << "512 bytes:\n"; avgDelayNS = wsModule.Calculate_AVG_Delay(ip, 512, pingIterations); break; case 2: file << "1024 bytes:\n"; avgDelayNS = wsModule.Calculate_AVG_Delay(ip, 1024, pingIterations); break; case 3: file << "1500 bytes:\n"; avgDelayNS = wsModule.Calculate_AVG_Delay(ip, 1500, pingIterations); break; case 4: file << "2048 bytes:\n"; avgDelayNS = wsModule.Calculate_AVG_Delay(ip, 2048, pingIterations); break; }

printf("Average Delay: %d ns, ", avgDelayNS); printf("Highest Delay: %d ns, ", wsModule.GetHighest()); printf("Lowest Delay: %d ns ", wsModule.GetLowest()); printf("Loss: %f \n",(double)wsModule.GetLost()/ pingIterations); std::ostringstream os; os << (double)wsModule.GetLost() / pingIterations; file << "AvrageDelay (ns) HighestDelay (ns) LowestDelay (ns) Loss(%): \n"; file << avgDelayNS << "" << wsModule.GetHighest() << "" << wsModule.GetLowest() <<"" << os.str() << "\n"; file << "\n"; } file.close(); } else //Time data {

50 int high = -1; int lowest = 999999999; wsModule.Clear_PacketLoss_Vector(); for (int i = 0; i < iterations; i++) { //Send data timeMS = wsModule.UDP_Send_Data(ip, i, packetSize);

timetotal += timeMS; if (timeMS > high) { high = timeMS; }

if (timeMS < lowest) { lowest = timeMS; }

} printf("Average time: %d, Highest Time: %d, Lowest Time: %d\n", timetotal / iterations, high, lowest);

wsModule.Calcualet_Loss(); printf("Average Loss: %f, ", wsModule.GetAverageLoss()); printf("Highest Loss: %f, ", wsModule.GetHighestLoss()); printf("Lowest Loss: %f \n", wsModule.GetLowestLoss());

std::string filename = ""; for (int i = 1; i < argc; i++) { filename.append(argv[i]); filename.append(""); }

file.open("../Logs/" + filename + ".tsv"); file << filename << "\n"; file << "Packet Size: " << packetSize << " B\n"; file << "AverageTime (ms) HighestTime (ms) LowestTime (ms)\n"; file << timetotal / iterations << "" << high << "" << lowest << "\n"; file << "\n"; file << "AverageLoss HighestLoss LowestLoss\n"; std::ostringstream os; os << (double)wsModule.GetAverageLoss() << "" << (double)wsModule.GetHighestLoss() << "" << (double)wsModule.GetLowestLoss() << "\n"; file << os.str();

file.close(); }

51 } else //Is set to be reciver { if (ping == true) { while (true) wsModule.UDP_Update(); //Only need to update } else { while (true) wsModule.UDP_WaitForData(packetSize); //Only need to update }

} }

wsModule.Shutdown(); #pragma endregion Winsoc

}

#pragma region else //RakNet { rnModule.Initialize();

if (isSender) { rnModule.Connect(ip);

//Wait until handshake is completed while (rnModule.GetIsConnected() != true) { rnModule.Update(); }

if (ping) { std::string filename = ""; for (int i = 1; i < argc; i++) { filename.append(argv[i]); filename.append(""); } std::ostringstream os; os << pingIterations; file.open("../Logs/" + filename + "" + os.str() + ".tsv");

52 file << filename << "\n"; file << "Nummber of Iterations: " << pingIterations << "\n"; //Take avg delay of the connection for (int i = 0; i < 5; i++) { switch (i) { case 0: file << "4 bytes:\n"; avgDelayNS = rnModule.Calculate_AVG_Delay(4, pingIterations); break; case 1: file << "512 bytes:\n"; avgDelayNS = rnModule.Calculate_AVG_Delay(512, pingIterations); break; case 2: file << "1024 bytes:\n"; avgDelayNS = rnModule.Calculate_AVG_Delay(1024, pingIterations); break; case 3: file << "1500 bytes:\n"; avgDelayNS = rnModule.Calculate_AVG_Delay(1500, pingIterations); break; case 4: file << "2048 bytes:\n"; avgDelayNS = rnModule.Calculate_AVG_Delay(2048, pingIterations); break; }

printf("Average Delay: %d ns, ", avgDelayNS); printf("Highest Delay: %d ns, ", rnModule.GetHighest()); printf("Lowest Delay: %d ns \n", rnModule.GetLowest());

file << "AvrageDelay (ns) HighestDelay (ns) LowestDelay (ns)\n"; file << avgDelayNS << "" << rnModule.GetHighest() << "" << rnModule.GetLowest() << "\n"; file << "\n"; } file.close(); } else { //Start Timer rnModule.Clock_Start();

//Send data rnModule.SendData();

//Recive Last ack while (rnModule.GetTransferComplete() == false) {

53 rnModule.Update(); }

//Stop timer timeMS = rnModule.Clock_Stop(true);

//Take time - avg delay printf("Total Time: %d\n", timeMS); }

} else { if (ping) { while (true) rnModule.Update(); } else { while (true) rnModule.WaitForData(); }

}

rnModule.Shutdown(); }

#pragma endregion OldRakNet

} else { printf("Failed to initialize the program because of bad parameters"); }

printf("Ending program \n");

return 0; }

54 A.2 NetworkService.h

#ifndef NETWORKSERVICE_H #define NETWORKSERVICE_H

#include #include class NetworkService { private: public: static int sendMessage(SOCKET curSocket, char* message, int messageSize); static int receiveMessage(SOCKET curSocket, char* buffer, int bufSize);

};

#endif

55 A.3 NetworkService.cpp

#include "NetworkService.h" int NetworkService::sendMessage(SOCKET curSocket, char * message, int messageSize) { return send(curSocket, message, messageSize, 0); //0 is for flags } int NetworkService::receiveMessage(SOCKET curSocket, char * buffer, int bufSize) { return recv(curSocket, buffer, bufSize, 0); //if no error, returns the number of bytes received and the buffer, else error code }

56 A.4 NetworkData.h

#ifndef NETWORKDATA_H #define NETWORKDATA_H

#define MAX_PACKET_SIZE 100000

#define GIGABYTE = 1073741824; const int DATA_SIZE = 1073741824; const int UDP_BUFFER_SIZE = 100000; const int TCP_BUFFER_SIZE = 1024000 * 300; //Mb * 300 const int OS_BUFFERS_SIZE = 1024000 * 300; const int MESSAGE_BUFFER_SIZE = 200; //const int PING_ITERATIONS = 100; //Obsoulete //const int UDP_PACKET_SIZE = 10240; //const int TCP_PACKET_SIZE = 61440;

#include #include enum PacketHeader { DATA = 0, CONNECTION_REQUEST, CLOCK_SYNC, CLOCK_SYNC_RESPONSE, TRANSFER_COMPLETE,

}; enum Protocol { NONE = 0, TCP, TCP_WITH_NODELAY, UDP, RAKNET, }; struct Packet { PacketHeader packet_type; //4 bytes

}; struct DataPacket { PacketHeader packet_type; //4 bytes int nrOfPackets; //4 bytes int ID; //4 bytes

57 char data[100]; //100 bytes

}; struct RakNetPacket { unsigned char typeId;

}; struct RakNetDataPacket { unsigned char typeId; char data[10000]; //100 bytes };

#endif

58 A.5 WinsocModule.h

#ifndef WINSOCMODULE_H #define WINSOCMODULE_H

#define _WINSOCK_DEPRECATED_NO_WARNINGS

#pragma comment(lib, "Ws2_32.lib") #include #include #include #include #include "NetworkData.h" #include "NetworkService.h" #include #include #include

#ifdef _WIN64 #define PACKETOFFSET 8 #else #define PACKETOFFSET 4 #endif

#define RECIVER_PORT "6881" #define SENDER_PORT "6882" class WinsocModule { private: SOCKET m_TCP_ListnerSocket; SOCKET m_TCP_SenderSocket; SOCKET m_TCP_ConenctedSocket; //TEMP SOCKET m_UDP_Socket;

int m_ClientID; int m_PacketID; std::string m_IP;

Protocol m_CurrentProtocol; char* network_data; char* UDP_network_data; char* network_message; sockaddr_in m_RecvAddr;

std::chrono::time_point m_start_time; std::vector m_ping_times; std::vector m_packet_loss;

59 bool m_ping_in_progress; int m_Avg_Delay; bool isConnected; bool tranferComplete; int dataCounter; int m_currentID; int m_missedPackets; int data_total; int highest; int lowest; double averageLoss; double highestLoss; double lowestLoss; int currentIteration;

timeval timeout; fd_set fds; public: private: bool AcceptNewClient(); void ReadMessagesFromClients();

int GetMyIp();

int TCP_Initialize(bool noDelay, bool isSender); int UDP_Initialize();

float GetAvrgRTT(); public: WinsocModule(); ~WinsocModule();

int Initialize(Protocol newProtocol, bool isSender); int Shutdown(); void Update(); void TCP_Update(); void TCP_WaitForData(); void UDP_WaitForData(int packetSize); void UDP_Update(); int TCP_Connect(char* ip);

void TCP_Send(PacketHeader headertype); int TCP_Send_Data(int packetSize); void UDP_Send(PacketHeader headertype, char* ip); int UDP_Send_Data(char* ip, int iteration, int packetSize);

int Calculate_AVG_Delay(int packetsize, int pingIterations); //TCP

60 int Calculate_AVG_Delay(char* ip, int packetsize, int pingIterations); //UDP void Clear_PacketLoss_Vector(); void Calcualet_Loss(); bool GetIsConnected(); bool GetTransferComplete(); void Clock_Start(); int Clock_Stop(bool ms=false); int GetHighest(); int GetLowest(); int GetLost(); double GetAverageLoss(); double GetHighestLoss(); double GetLowestLoss(); };

#endif;

61 A.6 WinsocModule.cpp

#include "WinsocModule.h"

WinsocModule::WinsocModule() { this->m_ClientID = 0; this->m_PacketID = 0;

this->m_CurrentProtocol = Protocol::NONE; this->m_ping_in_progress = false; this->m_Avg_Delay = 0; this->isConnected = false; this->tranferComplete = false; this->dataCounter = 0; this->m_currentID = 0; this->m_missedPackets = 0; this->network_data = new char[TCP_BUFFER_SIZE]; this->UDP_network_data = new char[UDP_BUFFER_SIZE]; this->network_message = new char[MESSAGE_BUFFER_SIZE]; this->highest = -1; this->lowest = 9999999; currentIteration = 0; }

WinsocModule::~WinsocModule() { this->Shutdown(); } int WinsocModule::Initialize(Protocol newProtocol, bool isSender) { printf("Initializing Network module... \n");

WSADATA wsaData;

// Initialize Winsock int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { printf("WSAStartup failed with error: %d\n", iResult); return 0; }

//Chose what protocol to initialize the sockets with if (newProtocol == Protocol::TCP) { if (this->TCP_Initialize(false, isSender)) {

62 //Success this->m_CurrentProtocol = newProtocol; printf("Network module Initialized with type %d protocol\n", this->m_CurrentProtocol); } else { //Error printf("Network module Initialization FAILED with type %d protocol\n", this->m_CurrentProtocol); } } else if (newProtocol == Protocol::TCP_WITH_NODELAY) { if (this->TCP_Initialize(true, isSender)) { this->m_CurrentProtocol = newProtocol; printf("Network module Initialized with type %d protocol\n", this->m_CurrentProtocol); } else { printf("Network module Initialization FAILED with type %d protocol\n", this->m_CurrentProtocol); } } else if (newProtocol == Protocol::UDP) { if (this->UDP_Initialize()) { this->m_CurrentProtocol = newProtocol; printf("Network module Initialized with type %d protocol\n", this->m_CurrentProtocol); } else { printf("Network module Initialization FAILED with type %d protocol\n", this->m_CurrentProtocol); } }

return 1; } int WinsocModule::Shutdown() { if (this->m_TCP_ListnerSocket != INVALID_SOCKET) { closesocket(this->m_TCP_ListnerSocket); WSACleanup(); }

63 if (this->m_TCP_SenderSocket != INVALID_SOCKET) { closesocket(this->m_TCP_SenderSocket); WSACleanup(); }

if (this->m_UDP_Socket != INVALID_SOCKET) { closesocket(this->m_UDP_Socket); WSACleanup(); }

delete[] this->network_data; delete[] this->UDP_network_data; delete[] this->network_message;

this->network_data = nullptr; this->UDP_network_data = nullptr; this->network_message = nullptr;

this->m_CurrentProtocol = Protocol::NONE; return 0; } void WinsocModule::Update() { if (this->m_CurrentProtocol == Protocol::UDP) { this->UDP_Update(); } else { this->TCP_Update(); } } void WinsocModule::TCP_Update() { this->AcceptNewClient(); // Get any new clients this->ReadMessagesFromClients(); //Read messages } void WinsocModule::UDP_Update() {

struct sockaddr_in si_other; int slen = sizeof(si_other); int data_length; unsigned int header = -1; int data_read = 0; Packet p; DataPacket dp;

64 // Setup timeval variable. If 0,0 it will return imedietly timeval timeout; timeout.tv_sec = 1; timeout.tv_usec = 0;

// Setup fd_set structure fd_set fds; FD_ZERO(&fds); FD_SET(this->m_UDP_Socket, &fds);

// Return value: // -1: error occurred // 0: timed out // > 0: data ready to be read int retval = select(this->m_UDP_Socket + 1, &fds, NULL, NULL, &timeout); if (retval == -1) { printf("Error, something went wrong with the ’select’ function\n"); return; } else if (retval == 0) { this->m_missedPackets++; printf("Timeout, No incoming data. Current Loss: %d\n", this->m_missedPackets); this->m_ping_in_progress = false; return; }

//try to receive some data, this is a blocking call data_length = recvfrom(this->m_UDP_Socket, this->network_message, MESSAGE_BUFFER_SIZE, 0, (struct sockaddr *) &si_other, &slen);

// If there was no data if (data_length <= 0) { //No data recieved, end the function return; } while (data_read != data_length) { //Read the header (skip the first 4 bytes since it is virtual function information) memcpy(&header, &this->network_message[data_read], sizeof(PacketHeader));

switch (header) {

case CLOCK_SYNC: //Resend a PING_RESPONSE this->UDP_Send(CLOCK_SYNC_RESPONSE, inet_ntoa(si_other.sin_addr)); //printf("Recived CLOCK_SYNC Packet \n");

65 data_read += sizeof(Packet); break;

case CLOCK_SYNC_RESPONSE:

this->Clock_Stop(); //printf("Recived CLOCK_SYNC_RESPONSE Packet \n"); data_read += sizeof(Packet); return; break;

case CONNECTION_REQUEST: data_read += sizeof(Packet);

//printf("Recived CONNECTION_REQUEST Packet \n"); break;

case DATA: memcpy(&dp, &this->network_message[data_read], sizeof(DataPacket)); //printf("Recived DATA Packet %d of %d, Expected ", dp.ID, dp.nrOfPackets); //printf("%d \n", (this->dataCounter + 1)); this->dataCounter++; if (this->dataCounter == dp.nrOfPackets) { this->UDP_Send(PacketHeader::TRANSFER_COMPLETE, inet_ntoa(si_other.sin_addr)); }

data_read += sizeof(DataPacket);

break;

case TRANSFER_COMPLETE: //printf("Recived TRANSFER_COMPLETE Packet \n"); memcpy(&this->m_missedPackets, &this->network_message[data_read+4], sizeof(int));; data_read += 8; this->m_packet_loss.push_back(this->m_missedPackets); this->tranferComplete = true; this->dataCounter = 0; break;

default: printf("Unkown packet type %d\n", header); data_read = data_length; break; }

}

}

66 int WinsocModule::TCP_Connect(char * ip) { addrinfo *result = NULL; addrinfo *ptr = NULL; addrinfo hints;

//if (this->m_IP == ip) //if my_ip is the same as the ip we try to connect to //{ // printf("Cannot connect to %s as it is this machines local ip\n", ip); // return 0; //} //else //{ ZeroMemory(&hints, sizeof(hints)); // Empties hint hints.ai_family = AF_INET; // The version 4 (IPv4) address family hints.ai_socktype = SOCK_STREAM; // Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism hints.ai_protocol = IPPROTO_TCP; // Set to use TCP

// Resolve the server address and port int iResult = getaddrinfo(ip, RECIVER_PORT, &hints, &result);

if (iResult != 0) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return 0; }

// Attempt to connect to an address until one succeeds for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {

// Set connectSocket to the host information this->m_TCP_SenderSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);

if (this->m_TCP_SenderSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); WSACleanup(); return 0; }

printf("Trying to connect to host...\n"); iResult = SOCKET_ERROR;

// Try to connect to host. This may take up to 20 seconds iResult = connect(this->m_TCP_SenderSocket, ptr->ai_addr, (int)ptr->ai_addrlen);

67 if (iResult == SOCKET_ERROR) { closesocket(this->m_TCP_SenderSocket); this->m_TCP_SenderSocket = INVALID_SOCKET; printf("The host %s is down... did not connect\n", ip); return 0; } }

// No longer need address info for server freeaddrinfo(result);

// If connection failed if (this->m_TCP_SenderSocket == INVALID_SOCKET) { printf("Unable to connect to server!\n"); WSACleanup(); return 0; }

// Set the mode of the socket to be nonblocking u_long iMode = 1; iResult = ioctlsocket(this->m_TCP_SenderSocket, FIONBIO, &iMode); if (iResult == SOCKET_ERROR) { printf("ioctlsocket failed with error: %d\n", WSAGetLastError()); closesocket(this->m_TCP_SenderSocket); WSACleanup(); return 0; } int value = OS_BUFFERS_SIZE; setsockopt(this->m_TCP_SenderSocket, SOL_SOCKET, SO_SNDBUF, (char*)value, sizeof(int) ); //TCP Options if (iResult == SOCKET_ERROR) { printf("incressing sender buffer failed with error: %d\n", WSAGetLastError()); closesocket(this->m_TCP_SenderSocket); WSACleanup(); return 0; } value = OS_BUFFERS_SIZE; iResult = setsockopt(this->m_TCP_SenderSocket, SOL_SOCKET, SO_RCVBUF, (char*)value, sizeof(int)); if (iResult == SOCKET_ERROR) { printf("incressing reciver buffer failed with error: %d\n", WSAGetLastError()); closesocket(this->m_UDP_Socket);

68 WSACleanup(); return 0; }

//Send CONNECTION_REQUEST package const unsigned int packet_size = sizeof(Packet);

Packet packet; packet.packet_type = CONNECTION_REQUEST;

// Send the packet directly to the host NetworkService::sendMessage(this->m_TCP_SenderSocket, reinterpret_cast(&packet), packet_size); printf("Sent CONNECTION_REQUEST to host\n");

// Add the host to connectedClients before getting a CONNECTION_ACCEPTED back // since we need to know which client to listen for

this->m_ClientID++; this->isConnected = true;

return 1; //}

} bool WinsocModule::AcceptNewClient() { SOCKET otherClientSocket; // If client waiting, accept the connection and save the socket otherClientSocket = accept(this->m_TCP_ListnerSocket, NULL, NULL);

if (otherClientSocket != INVALID_SOCKET) {

if (this->m_CurrentProtocol == Protocol::TCP_WITH_NODELAY) { // Disable the nagle effect on the client’s socket char value = 1; setsockopt(otherClientSocket, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value)); //TCP Options } int value = OS_BUFFERS_SIZE;

setsockopt(otherClientSocket, SOL_SOCKET, SO_SNDBUF, (char*)value, sizeof(int)); //TCP Options setsockopt(otherClientSocket, SOL_SOCKET, SO_RCVBUF, (char*)value, sizeof(int));

this->m_TCP_ConenctedSocket = otherClientSocket; this->m_TCP_SenderSocket = otherClientSocket;

69 printf("client %d has been connected to the server\n", this->m_ClientID); this->m_ClientID++; this->isConnected = true;

return true; }

return false; } void WinsocModule::ReadMessagesFromClients() {

// The data buffer that will hold the incoming data unsigned int header = -1; // The header variable that will hold the loaded header int old = -1; // The objects to load the data into Packet p; DataPacket dp;

//Check if there is data int data_length = NetworkService::receiveMessage(this->m_TCP_SenderSocket, this->network_message, MESSAGE_BUFFER_SIZE); int data_read = 0;

// If there was no data if (data_length <= 0) { //No data recieved, end the function return; }

while (data_read != data_length) { //Read the header (skip the first 4 bytes since it is virtual function information) //memcpy(&header, &this->network_data[data_read], sizeof(PacketHeader)); header = this->network_message[data_read]; switch (header) {

case CLOCK_SYNC : //Resend a PING_RESPONSE this->TCP_Send(CLOCK_SYNC_RESPONSE); //printf("Recived CLOCK_SYNC Packet \n"); data_read += sizeof(Packet); break;

case CLOCK_SYNC_RESPONSE:

70 this->Clock_Stop(); //printf("Recived CLOCK_SYNC_RESPONSE Packet \n"); data_read += sizeof(Packet); break;

case CONNECTION_REQUEST : data_read += sizeof(Packet);

//printf("Recived CONNECTION_REQUEST Packet \n"); break;

case DATA: old = data_read; memcpy(&dp, &network_data[data_read], sizeof(DataPacket)); //printf("Recived DATA Packet %d of %d, Expected ", dp.ID, dp.nrOfPackets); //printf("%d \n",(this->dataCounter + 1) ); this->dataCounter++; if (this->dataCounter == dp.nrOfPackets) { this->TCP_Send(PacketHeader::TRANSFER_COMPLETE); }

data_read += sizeof(DataPacket);

break;

case TRANSFER_COMPLETE : //printf("Recived TRANSFER_COMPLETE Packet \n"); data_read += sizeof(Packet); this->tranferComplete = true; this->dataCounter = 0; break;

default: this->dataCounter++; printf("Unkown packet type %d, %d\n", header, this->dataCounter); data_read = data_length; break; }

}

} void WinsocModule::TCP_WaitForData() { int data_length = NetworkService::receiveMessage(this->m_TCP_SenderSocket, this->network_data, TCP_BUFFER_SIZE); int data_read = 0;

71 // If there was no data if (data_length <= 0) { //No data recieved, end the function return; }

this->data_total += data_length; printf("%d\n",this->data_total);

if (data_total >= DATA_SIZE) { this->TCP_Send(TRANSFER_COMPLETE); printf("Sent TRANSFER_COMPLETE\n"); data_total = 0; } } void WinsocModule::UDP_WaitForData(int packetSize) { int data_length = -1; int data_read = 0;

struct sockaddr_in si_other; int slen = sizeof(si_other);

timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 0;

fd_set fds; FD_ZERO(&fds); FD_SET(this->m_UDP_Socket, &fds);

int retval = select(this->m_UDP_Socket + 1, &fds, NULL, NULL, &timeout); if (retval == -1) { printf("Error, something went wrong with the ’select’ function\n"); } else if (retval == 0) { //printf("Timeout, No incoming data"); return; }

//try to receive some data, this is a blocking call if ((data_length = recvfrom(this->m_UDP_Socket, this->UDP_network_data, UDP_BUFFER_SIZE, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR) { printf("recvfrom() failed with error code : %d \n", WSAGetLastError()); //exit(EXIT_FAILURE); }

72 int id; int iteration; memcpy(&id,UDP_network_data,sizeof(int)); memcpy(&iteration, UDP_network_data+4, sizeof(int)); if (iteration != currentIteration) { return; } if (id == 1) //If we recive a new set of packages { //Reset the variables this->m_currentID = 0; this->data_total = 0; this->m_missedPackets = 0; } int dif = id - this->m_currentID; if (dif > 1) { this->m_missedPackets += dif-1; } this->m_currentID = id; this->data_total += data_length; //printf("%d, Loss: %d\n", this->data_total, this->m_missedPackets); if (data_total >= DATA_SIZE) { //this->UDP_Send(TRANSFER_COMPLETE, inet_ntoa(si_other.sin_addr));

this->m_RecvAddr.sin_addr.s_addr = inet_addr(inet_ntoa(si_other.sin_addr)); const unsigned int packet_size = sizeof(Packet);

char data[12]; int value = (int)TRANSFER_COMPLETE; memcpy(&data, &value, sizeof(int)); double loss = (double)(this->m_missedPackets / (double)(this->data_total / packetSize)); memcpy(&data[4], &loss, sizeof(double));

sendto(this->m_UDP_Socket, reinterpret_cast(&data), sizeof(data), 0, (struct sockaddr*) &this->m_RecvAddr, sizeof(this->m_RecvAddr));

printf("Sent TRANSFER_COMPLETE, Packages Recived: %d, Loss: %d\n", this->data_total/ packetSize, this->m_missedPackets); this->currentIteration++; this->data_total = 0;

73 this->m_missedPackets = 0; } } int WinsocModule::GetMyIp() { char ac[80]; struct in_addr addr;

if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR) { printf("failed to get local ip"); 0; }

struct hostent *phe = gethostbyname(ac); if (phe == 0) { printf("failed to get local ip"); 0; }

for (int i = 0; phe->h_addr_list[i] != 0; ++i) {

memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr)); } unsigned char b1 = addr.S_un.S_un_b.s_b1; unsigned char b2 = addr.S_un.S_un_b.s_b2; unsigned char b3 = addr.S_un.S_un_b.s_b3; unsigned char b4 = addr.S_un.S_un_b.s_b4;

// Stream the data as int into the string std::stringstream ss; ss << (int)b1 << "." << (int)b2 << "." << (int)b3 << "." << (int)b4;

this->m_IP.append(ss.str()); // Set my_ip to the local ip-address of the machine

return 1; } void WinsocModule::TCP_Send(PacketHeader headertype) { const unsigned int packet_size = sizeof(Packet);

Packet packet; packet.packet_type = headertype;

NetworkService::sendMessage(this->m_TCP_SenderSocket, reinterpret_cast(&packet), packet_size); } int WinsocModule::TCP_Send_Data(int packetSize)

74 { char* data = new char[packetSize];

//char data[TCP_PACKET_SIZE]; //const unsigned int packet_size = sizeof(data); int nrOfPackets = ceil(DATA_SIZE / packetSize)+1;

this->m_start_time = std::chrono::time_point::clock::now();

for(int i = 1; i <= nrOfPackets; i++) { NetworkService::sendMessage(this->m_TCP_SenderSocket, data, packetSize);

//printf("Sent DataPacket %d\n", i); }

//Recive Last ack while (this->tranferComplete == false) { this->TCP_Update(); }

auto end_time = std::chrono::time_point::clock::now();

int result = std::chrono::duration_cast(end_time - this->m_start_time).count();;

this->tranferComplete = false;

delete[] data; data = nullptr;

return result; } void WinsocModule::UDP_Send(PacketHeader headertype, char* ip) {

this->m_RecvAddr.sin_addr.s_addr = inet_addr(ip); const unsigned int packet_size = sizeof(Packet);

Packet packet; packet.packet_type = headertype;

sendto(this->m_UDP_Socket, reinterpret_cast(&packet), packet_size, 0, (struct sockaddr*) &this->m_RecvAddr, sizeof(this->m_RecvAddr));

}

75 int WinsocModule::UDP_Send_Data(char * ip, int iteration, int packetSize) {

this->m_RecvAddr.sin_addr.s_addr = inet_addr(ip); //Se if we recived a response struct sockaddr_in si_other; int slen = sizeof(si_other); int data_length; unsigned int header = -1; int data_read = 0; double loss;

// Setup timeval variable. If 0,0 it will return imedietly timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 0;

char data[61440]; //char data[UDP_PACKET_SIZE]; //const unsigned int packet_size = sizeof(*data); int id = 0; sockaddr* add = (struct sockaddr*) &this->m_RecvAddr; int addS = sizeof(this->m_RecvAddr);

this->m_start_time = std::chrono::time_point::clock::now();

while(this->tranferComplete != true) { id++; memcpy(&data, &id, sizeof(int)); memcpy(&data[4], &iteration, sizeof(int)); //Which iteration the packet is from if (sendto(this->m_UDP_Socket, data, packetSize, 0, (struct sockaddr*) &this->m_RecvAddr, sizeof(this->m_RecvAddr)) == SOCKET_ERROR) { printf("send failed\n"); } else { //printf("Sent DataPacket %d\n", id); }

// Setup fd_set structure fd_set fds; FD_ZERO(&fds); FD_SET(this->m_UDP_Socket, &fds);

// Return value: // -1: error occurred // 0: timed out

76 // > 0: data ready to be read int retval = select(this->m_UDP_Socket + 1, &fds, NULL, NULL, &timeout); if (retval == -1) { printf("Error, something went wrong with the ’select’ function\n"); } else if (retval == 0) { //printf("Timeout, No incoming data. Current Loss: %d\n", this->m_missedPackets); } else //There where data { //try to receive some data, this is a blocking call data_length = recvfrom(this->m_UDP_Socket, this->network_message, MESSAGE_BUFFER_SIZE, 0, (struct sockaddr *) &si_other, &slen);

while (data_read != data_length) { //Read the header (skip the first 4 bytes since it is virtual function information) memcpy(&header, &this->network_message[data_read], sizeof(PacketHeader));

switch (header) { case TRANSFER_COMPLETE: //printf("Recived TRANSFER_COMPLETE Packet \n"); memcpy(&loss, &this->network_message[data_read + 4], sizeof(double));;

this->m_packet_loss.push_back(loss); this->tranferComplete = true; data_read += 12; this->dataCounter = 0; break;

default: printf("Unkown packet type %d\n", header); data_read = data_length; break; }

} }

} auto end_time = std::chrono::time_point::clock::now(); int result = std::chrono::duration_cast(end_time - this->m_start_time).count();; this->tranferComplete = false; return result;

77 } float WinsocModule::GetAvrgRTT() { float result = 0; int count = 0; std::vector::iterator itr;

for (itr = this->m_ping_times.begin(); itr != this->m_ping_times.end();) { result += *itr._Ptr; count++; itr++; }

result = result / count;

return result; } int WinsocModule::Calculate_AVG_Delay(int packetsize, int pingIterations) { /* 1. Start a timer to measure teh RTT 2. Send a CLOCK_SYNC packet which will trigger the reciver to send back a CLOCK_SYNC_RESPONSE packet with their original time 3. Wait for the packet to arrive 4. Repeat three times to get more RTT values for an average 5. Calculate the average RTT 6. Add half of RTT to get estamate travel time for the connection */

//Clear any reamining times this->m_ping_times.clear(); this->highest = -1; this->lowest = 9999999; this->m_missedPackets = 0; char* data = nullptr;

switch (packetsize) { case 4: data = new char[4]; break; case 512: data = new char[512]; break; case 1024: data = new char[1024]; break;

78 case 1500: data = new char[1500]; break; case 2048: data = new char[2048]; break; } printf("Packetsize: %d\n", packetsize);

//Add the header at the begining of the data int value = (int)CLOCK_SYNC; memcpy(data, &value, sizeof(int)); for (int i = 0; i < pingIterations; i++) { // Set current time this->m_start_time = std::chrono::time_point::clock::now(); // Set to not send more pings since it will disrupt the timers this->m_ping_in_progress = true;

//Send the packet NetworkService::sendMessage(this->m_TCP_SenderSocket, data, sizeof(data));

//Wait for the message until it arrives, When it does it will set the variable to false and end the loop while (this->m_ping_in_progress) { this->ReadMessagesFromClients(); }

} float total = 0; int count = 0; std::vector::iterator itr; std::ofstream file; std::ostringstream os; os << "../Logs/" << packetsize << "" << pingIterations << ".txt"; file.open(os.str()); for (itr = this->m_ping_times.begin(); itr != this->m_ping_times.end();) { int value = *itr._Ptr / 2; //We only care of one-way time

if (value > this->highest) { this->highest = value; }

if (value < this->lowest)

79 { this->lowest = value; } file << value << "\n"; total += value; count++; itr++; }

file.close(); this->m_Avg_Delay = (total / count); //nano-seconds

delete[] data;

return this->m_Avg_Delay; } int WinsocModule::Calculate_AVG_Delay(char * ip, int packetsize, int pingIterations) { /* 1. Start a timer to measure teh RTT 2. Send a CLOCK_SYNC packet which will trigger the reciver to send back a CLOCK_SYNC_RESPONSE packet with their original time 3. Wait for the packet to arrive 4. Repeat three times to get more RTT values for an average 5. Calculate the average RTT 6. Add half of RTT to get estamate travel time for the connection */

//Clear any reamining times

this->m_RecvAddr.sin_addr.s_addr = inet_addr(ip); this->m_ping_times.clear(); this->highest = -1; this->lowest = 9999999; this->m_missedPackets = 0; char* data = nullptr;

switch (packetsize) { case 4: data = new char[4]; break; case 512: data = new char[512]; break; case 1024: data = new char[1024]; break; case 1500:

80 data = new char[1500]; break; case 2048: data = new char[2048]; break; } printf("Packetsize: %d\n", packetsize);

//Add the header at the begining of the data int value = (int)CLOCK_SYNC; memcpy(data, &value, sizeof(int)); for (int i = 0; i < pingIterations; i++) { // Set current time this->m_start_time = std::chrono::time_point::clock::now();

// Set to not send more pings since it will disrupt the timers this->m_ping_in_progress = true;

//Send the packet //this->UDP_Send(CLOCK_SYNC, ip);

sendto(this->m_UDP_Socket, data, sizeof(data), 0, (struct sockaddr*) &this->m_RecvAddr, sizeof(this->m_RecvAddr));

while (this->m_ping_in_progress) { this->UDP_Update(); }

} float total = 0; int count = 0; std::vector::iterator itr; std::ofstream file; std::ostringstream os; os << "../Logs/" << packetsize << "" << pingIterations << ".txt"; file.open(os.str()); for (itr = this->m_ping_times.begin(); itr != this->m_ping_times.end();) { int value = *itr._Ptr / 2; //We only care of one-way time

if (value > this->highest) { this->highest = value; }

81 if (value < this->lowest) { this->lowest = value; } file << value << "\n"; total += value; count++; itr++; }

file.close(); this->m_Avg_Delay = (total / count); //nano-seconds

delete[] data;

return this->m_Avg_Delay; } void WinsocModule::Clear_PacketLoss_Vector() { this->m_packet_loss.clear(); } void WinsocModule::Calcualet_Loss() { float result = 0; int count = 0; std::vector::iterator itr; this->highestLoss = -1; this->lowestLoss = 9999999;

for (itr = this->m_packet_loss.begin(); itr != this->m_packet_loss.end();) { double value = (double)*itr._Ptr;

if (value > this->highestLoss) { this->highestLoss = value; }

if (value < lowestLoss) { this->lowestLoss = value; }

result += value; count++; itr++; }

82 this->averageLoss = (double)result / count;

} bool WinsocModule::GetIsConnected() { return this->isConnected; } bool WinsocModule::GetTransferComplete() { return this->tranferComplete; } int WinsocModule::TCP_Initialize(bool noDelay, bool isSender) { this->m_TCP_ListnerSocket = INVALID_SOCKET; // The socket that will listen int iResult;

// Address info for the listenSocket to listen to struct addrinfo *result = NULL; struct addrinfo hints;

// Set address information ZeroMemory(&hints, sizeof(hints)); // Empties hints hints.ai_family = AF_INET; // The Internet Protocol version 4 (IPv4) address family hints.ai_socktype = SOCK_STREAM; // Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism hints.ai_protocol = IPPROTO_TCP; // Set to use TCP hints.ai_flags = AI_PASSIVE; // The socket address will be used in a call to the bind function

// Resolve the server address and port if (isSender) { iResult = getaddrinfo(NULL, SENDER_PORT, &hints, &result); //NULL = Dont need addres since it will be on local machine } else { iResult = getaddrinfo(NULL, RECIVER_PORT, &hints, &result); //NULL = Dont need addres since it will be on local machine }

if (iResult != 0) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return 0; }

83 // Create a SOCKET for connecting to server this->m_TCP_ListnerSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);

if (this->m_TCP_ListnerSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 0; }

// Set the mode of the socket to be nonblocking u_long iMode = 1; iResult = ioctlsocket(this->m_TCP_ListnerSocket, FIONBIO, &iMode);

if (iResult == SOCKET_ERROR) { printf("ioctlsocket failed with error: %d\n", WSAGetLastError()); closesocket(this->m_TCP_ListnerSocket); WSACleanup(); return 0; }

// Setup the listening socket iResult = bind(this->m_TCP_ListnerSocket, result->ai_addr, (int)result->ai_addrlen);

if (iResult == SOCKET_ERROR) { printf("bind failed with error: %d\n", WSAGetLastError()); freeaddrinfo(result); closesocket(this->m_TCP_ListnerSocket); WSACleanup(); return 0; }

// No longer need address information freeaddrinfo(result);

// Start listening for new clients attempting to connect iResult = listen(this->m_TCP_ListnerSocket, SOMAXCONN);

if (iResult == SOCKET_ERROR) { printf("listen failed with error: %d\n", WSAGetLastError()); closesocket(this->m_TCP_ListnerSocket); WSACleanup(); return 0; }

this->GetMyIp();

return 1; }

84 int WinsocModule::UDP_Initialize() { sockaddr_in local; int iResult;

this->GetMyIp();//Set the local ip

local.sin_family = AF_INET; local.sin_addr.s_addr = INADDR_ANY; local.sin_port = 6881; // choose any

// create the socket this->m_UDP_Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // bind to the local address

iResult = bind(this->m_UDP_Socket, (sockaddr *)&local, sizeof(local));

if (iResult == SOCKET_ERROR) { printf("bind failed with error: %d\n", WSAGetLastError()); closesocket(this->m_UDP_Socket); WSACleanup(); return 0; }

//int value = OS_BUFFERS; //iResult = setsockopt(this->m_UDP_Socket, SOL_SOCKET, SO_RCVBUF, (char*)value, sizeof(int)); //if (iResult == SOCKET_ERROR) { // printf("incressing reciver buffer failed with error: %d\n", WSAGetLastError()); // closesocket(this->m_UDP_Socket); // WSACleanup(); // return 0; //}

//value = OS_BUFFERS; // Set the value again if we want to change it //setsockopt(this->m_UDP_Socket, SOL_SOCKET, SO_SNDBUF, (char*)value, sizeof(int)); //if (iResult == SOCKET_ERROR) { // printf("incressing sender buffer failed with error: %d\n", WSAGetLastError()); // closesocket(this->m_UDP_Socket); // WSACleanup(); // return 0; //}

this->m_RecvAddr.sin_family = AF_INET; this->m_RecvAddr.sin_port = 6881;

return 1; }

85 void WinsocModule::Clock_Start() { // Set current time this->m_start_time = std::chrono::time_point::clock::now();

// Set to not send more pings since it will disrupt the timers this->m_ping_in_progress = true; } int WinsocModule::Clock_Stop(bool ms) { int result = 0;

//Get the end time auto end_time = std::chrono::time_point::clock::now();

//Calculate the delta time togheter with end and start time to nano-seconds if (ms) { result = std::chrono::duration_cast(end_time - this->m_start_time).count(); } else { result = std::chrono::duration_cast(end_time - this->m_start_time).count();

}

//Push back the result this->m_ping_times.push_back(result);

//Set piong in progress to false this->m_ping_in_progress = false;

return result; } int WinsocModule::GetHighest() { return this->highest; } int WinsocModule::GetLowest() { return this->lowest; } int WinsocModule::GetLost()

86 { return this->m_missedPackets; } double WinsocModule::GetAverageLoss() { return this->averageLoss; } double WinsocModule::GetHighestLoss() { return this->highestLoss; } double WinsocModule::GetLowestLoss() { return this->lowestLoss; }

87 A.7 RakNetModule.h

#ifndef RAKNETMODULE_H #define RAKNETMODULE_H

#include "MessageIdentifiers.h" #include "RakPeerInterface.h" #include "RakNetTypes.h" #include "MessageIdentifiers.h" #include "BitStream.h" #include "NetworkData.h" #include #include #include #include

#define DEFAULT_PORT "6881" class RakNetModule { private: RakNet::RakPeerInterface* peer; RakNet::SocketDescriptor socketDescriptor;

std::chrono::time_point m_start_time; std::vector m_ping_times; bool m_ping_in_progress; int m_Avg_Delay; bool transferComplete; bool isConnected; int dataCounter; int data_total; int highest; int lowest; public: private:

float GetAvrgRTT(); public: RakNetModule(); ~RakNetModule();

bool Initialize(); void Shutdown();

void Update(); void WaitForData();

88 bool Connect(char* ip); void Send(DefaultMessageIDTypes id, PacketPriority priority, PacketReliability reliability); void SendData();

int Calculate_AVG_Delay(int packetsize, int pingIteration); void Clock_Start(); int Clock_Stop(bool ms = false); bool GetTransferComplete(); bool GetIsConnected(); int GetHighest(); int GetLowest(); };

#endif

89 A.8 RakNetModule.cpp

#include "RakNetModule.h" void RakNetModule::Clock_Start() { // Set current time this->m_start_time = std::chrono::time_point::clock::now();

// Set to not send more pings since it will disrupt the timers this->m_ping_in_progress = true; } int RakNetModule::Clock_Stop(bool ms) { int result = 0;

//Get the end time auto end_time = std::chrono::time_point::clock::now();

//Calculate the delta time togheter with end and start time to nano-seconds if (ms) { result = std::chrono::duration_cast(end_time - this->m_start_time).count(); } else { result = std::chrono::duration_cast(end_time - this->m_start_time).count(); }

//Push back the result this->m_ping_times.push_back(result);

//Set piong in progress to false this->m_ping_in_progress = false;

return result; } bool RakNetModule::GetTransferComplete() { return this->transferComplete; } bool RakNetModule::GetIsConnected() { return this->isConnected;

90 } int RakNetModule::GetHighest() { return this->highest; } int RakNetModule::GetLowest() { return this->lowest; } float RakNetModule::GetAvrgRTT() { float result = 0; int count = 0; std::vector::iterator itr;

for (itr = this->m_ping_times.begin(); itr != this->m_ping_times.end();) { result += *itr._Ptr; count++; itr++; }

result = result / count;

return result; }

RakNetModule::RakNetModule() { this->peer = nullptr; this->transferComplete = false; this->isConnected = false; this->dataCounter = 0; this->data_total = 0; this->highest = -1; this->lowest = 9999999; }

RakNetModule::~RakNetModule() { } bool RakNetModule::Initialize() { this->peer = RakNet::RakPeerInterface::GetInstance(); this->socketDescriptor = RakNet::SocketDescriptor(6881, 0); socketDescriptor.socketFamily = AF_INET;

91 this->peer->Startup(3, &this->socketDescriptor, 1); this->peer->SetMaximumIncomingConnections(3);

return 1; } void RakNetModule::Shutdown() { this->peer->Shutdown(0); //Time until shutdown to inform connected clients delete this->peer; this->peer = nullptr; } void RakNetModule::Update() { RakNet::Packet* RaKpacket; RakNetPacket p; RakNetDataPacket* dp;

for (RaKpacket = peer->Receive(); RaKpacket; peer->DeallocatePacket(RaKpacket), RaKpacket = peer->Receive()) {

//p.deserialize((char*)RaKpacket->data);

switch (RaKpacket->data[0]) {

case ID_REMOTE_DISCONNECTION_NOTIFICATION: printf("Another client has disconnected.\n"); break; case ID_REMOTE_CONNECTION_LOST: printf("Another client has lost the connection.\n"); break; case ID_REMOTE_NEW_INCOMING_CONNECTION: printf("Another client has connected.\n"); break; case ID_CONNECTION_REQUEST_ACCEPTED: printf("Our connection request has been accepted.\n"); this->isConnected = true; break; case ID_NEW_INCOMING_CONNECTION: //this->Send(DefaultMessageIDTypes::R_START_PING, IMMEDIATE_PRIORITY, RELIABLE_SEQUENCED); printf("A connection is incoming.\n"); break; case ID_NO_FREE_INCOMING_CONNECTIONS: printf("The server is full.\n"); break; case ID_DISCONNECTION_NOTIFICATION: printf("A client has disconnected.\n");

92 break; case ID_CONNECTION_LOST: printf("A client lost the connection.\n"); break;

case R_START_PING: printf("Recived R_CLOCK_SYNC Packet\n"); this->Send(DefaultMessageIDTypes::R_CLOCK_SYNC, IMMEDIATE_PRIORITY, RELIABLE_SEQUENCED); break;

case R_CLOCK_SYNC: //printf("Recived R_CLOCK_SYNC Packet\n"); this->Send(DefaultMessageIDTypes::R_CLOCK_SYNC_RESPONSE, IMMEDIATE_PRIORITY, RELIABLE_SEQUENCED); break;

case R_CLOCK_SYNC_RESPONSE: //printf("Recived R_CLOCK_SYNC_RESPONSE Packet\n"); this->Clock_Stop(); break;

case R_CONNECTION_REQUEST: printf("Recived R_CONNECTION_REQUEST Packet\n"); break;

case R_DATA:

printf("Recived R_DATA Packet\n"); break;

case R_TRANSFER_COMPLETE : printf("Recived R_TRANSFER_COMPLETE Packet\n"); this->transferComplete = true; return; break;

default: printf("Unkown packet type %d\n", RaKpacket->data[0]); break; } }

} void RakNetModule::WaitForData() { RakNet::Packet* RaKpacket;

for (RaKpacket = peer->Receive(); RaKpacket; peer->DeallocatePacket(RaKpacket), RaKpacket = peer->Receive())

93 {

if (RaKpacket != nullptr) { this->data_total += sizeof(RaKpacket);

if (this->data_total >= DATA_SIZE) { this->Send(R_TRANSFER_COMPLETE, IMMEDIATE_PRIORITY, RELIABLE_SEQUENCED); this->data_total = 0; } }

} } bool RakNetModule::Connect(char * ip) { int r = this->peer->Connect(ip, 6881, 0, 0);

return 1; } void RakNetModule::Send(DefaultMessageIDTypes id, PacketPriority priority, PacketReliability reliability) { RakNetPacket packet; packet.typeId = id;

peer->Send(reinterpret_cast(&packet), sizeof(packet) , priority, reliability, 0, RakNet::UNASSIGNED_RAKNET_GUID, true); } void RakNetModule::SendData() { RakNetDataPacket packet; packet.typeId = R_DATA; int nrOfPackets = ceil(DATA_SIZE / (sizeof(RakNetDataPacket))); const unsigned int packet_size = sizeof(RakNetDataPacket);

for (int i = 1; i <= nrOfPackets; i++) { int j = peer->Send(reinterpret_cast(&packet), sizeof(packet), HIGH_PRIORITY, RELIABLE_SEQUENCED, 0, RakNet::UNASSIGNED_RAKNET_GUID, true);

printf("Sent DataPacket %d\n", i); }

}

94 int RakNetModule::Calculate_AVG_Delay(int packetsize, int pingIteration) { /* 1. Start a timer to measure teh RTT 2. Send a CLOCK_SYNC packet which will trigger the reciver to send back a CLOCK_SYNC_RESPONSE packet with their original time 3. Wait for the packet to arrive 4. Repeat three times to get more RTT values for an average 5. Calculate the average RTT 6. Add half of RTT to get estamate travel time for the connection */

//Clear any reamining times this->m_ping_times.clear(); this->highest = -1; this->lowest = 9999999; char* data = nullptr;

switch (packetsize) { case 4: data = new char[4]; break; case 512: data = new char[512]; break; case 1024: data = new char[1024]; break; case 1500: data = new char[1500]; break; case 2048: data = new char[2048]; break; } printf("Packetsize: %d\n", packetsize);

data[0] = DefaultMessageIDTypes::R_CLOCK_SYNC; for (int i = 0; i < pingIteration; i++) { //Start the clock //this->Clock_Start(); this->m_start_time = std::chrono::time_point::clock::now(); this->m_ping_in_progress = true;

//Send the packet

95 //this->Send(DefaultMessageIDTypes::R_CLOCK_SYNC, IMMEDIATE_PRIORITY, RELIABLE_SEQUENCED); peer->Send(data, sizeof(data), IMMEDIATE_PRIORITY, RELIABLE_SEQUENCED, 0, RakNet::UNASSIGNED_RAKNET_GUID, true);

//Wait for the message until it arrives, When it does it will set the variable to false and end the loop while (this->m_ping_in_progress) { this->Update(); }

}

float total = 0; int count = 0; std::vector::iterator itr; std::ofstream file; std::ostringstream os;

os <<"../Logs/" << packetsize << "" << pingIteration << ".txt"; file.open(os.str()); for (itr = this->m_ping_times.begin(); itr != this->m_ping_times.end();) { int value = *itr._Ptr / 2; //We only care of one-way time

if (value > this->highest) { this->highest = value; }

if (value < this->lowest) { this->lowest = value; } file << value << "\n"; total += value; count++; itr++; }

file.close(); this->m_Avg_Delay = (total / count); //nano-seconds

delete[] data;

return this->m_Avg_Delay; }

96 Appendix B

Modified RakNet Big Packet Test

Online Github Project: https://github.com/TobbetheStalker/RakNet

B.1 BigPacketTest.cpp

/* * Copyright (c) 2014, Oculus VR, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #include #include #include

#include "RakPeerInterface.h" #include "BitStream.h" #include // For atoi #include // For strlen #include "RakNetStatistics.h" #include "GetTime.h" #include "MessageIdentifiers.h" #include "MTUSize.h" #include #include "Kbhit.h" #include "RakSleep.h" #include "Gets.h" bool quit; bool sentPacket=false;

#define BIG_PACKET_SIZE 83886080 const int GB = 1073741824;

97 //83886080 //167772160 //41943040 using namespace RakNet;

RakPeerInterface *client, *server; char *text; int totalDatarecived = 0; int clientPacketLoss = 0; float serverPacketLoss = 0; int main(void) { std::ofstream file;

client=server=0;

text= new char [BIG_PACKET_SIZE]; quit=false; char ch;

printf("This is a test I use to test the packet splitting capabilities of RakNet\n"); printf("All it does is send a large block of data to the feedback loop\n"); printf("Difficulty: Beginner\n\n");

printf("Enter ’s’ to run as server, ’c’ to run as client, space to run local.\n"); ch=’’; Gets(text,BIG_PACKET_SIZE); ch=text[0];

if (ch==’c’) { client=RakNet::RakPeerInterface::GetInstance(); printf("Working as client\n"); printf("Enter remote IP: "); Gets(text,BIG_PACKET_SIZE); if (text[0]==0) strcpy(text, "natpunch.jenkinssoftware.com"); // dx in Europe } else if (ch==’s’) { server=RakNet::RakPeerInterface::GetInstance(); printf("Working as server\n"); } else { client=RakNet::RakPeerInterface::GetInstance();

98 server=RakNet::RakPeerInterface::GetInstance();; strcpy(text, "127.0.0.1"); }

// Test IPV6 int socketFamily; socketFamily=AF_INET; //socketFamily=AF_INET6; if (server) { server->SetTimeoutTime(5000,RakNet::UNASSIGNED_SYSTEM_ADDRESS); RakNet::SocketDescriptor socketDescriptor(3000,0); socketDescriptor.socketFamily=socketFamily; server->SetMaximumIncomingConnections(4); StartupResult sr; sr=server->Startup(4, &socketDescriptor, 1); if (sr!=RAKNET_STARTED) { printf("Server failed to start. Error=%i\n", sr); return 1; } // server->SetPerConnectionOutgoingBandwidthLimit(40000);

printf("Started server on %s\n", server->GetMyBoundAddress().ToString(true)); } if (client) { client->SetTimeoutTime(5000,RakNet::UNASSIGNED_SYSTEM_ADDRESS); RakNet::SocketDescriptor socketDescriptor(0,0); socketDescriptor.socketFamily=socketFamily; StartupResult sr; sr=client->Startup(4, &socketDescriptor, 1); if (sr!=RAKNET_STARTED) { printf("Client failed to start. Error=%i\n", sr); return 1; } client->SetSplitMessageProgressInterval(10000); // Get ID_DOWNLOAD_PROGRESS notifications // client->SetPerConnectionOutgoingBandwidthLimit(28800);

printf("Started client on %s\n", client->GetMyBoundAddress().ToString(true));

client->Connect(text, 3000, 0, 0); } RakSleep(500); printf("My IP addresses:\n"); RakPeerInterface *rakPeer; if (server)

99 rakPeer=server; else rakPeer=client; unsigned int i; for (i=0; i < rakPeer->GetNumberOfAddresses(); i++) { printf("%i. %s\n", i+1, rakPeer->GetLocalIP(i)); }

// Always apply the network simulator on two systems, never just one, with half the values on each. // Otherwise the flow control gets confused. // if (client) // client->ApplyNetworkSimulator(.01, 0, 0); // if (server) // server->ApplyNetworkSimulator(.01, 0, 0);

RakNet::TimeMS start,stop;

RakNet::TimeMS nextStatTime = RakNet::GetTimeMS() + 1000; RakNet::Packet *packet; start=RakNet::GetTimeMS(); while (!quit) { if (server) { for (packet = server->Receive(); packet; server->DeallocatePacket(packet), packet=server->Receive()) { if (packet->data[0]==ID_NEW_INCOMING_CONNECTION || packet->data[0]==253) { printf("Starting send\n"); start=RakNet::GetTimeMS();

/* if (BIG_PACKET_SIZE<=100000) { for (int i=0; i < BIG_PACKET_SIZE; i++) text[i]=255-(i&255); } else text[0]=(unsigned char) 255; */

text[0] = (unsigned char)255; int nrofpackets = (GB / BIG_PACKET_SIZE) + 1; for (int i = 0; i < nrofpackets; i++) { server->Send(text, BIG_PACKET_SIZE, HIGH_PRIORITY, RELIABLE_ORDERED_WITH_ACK_RECEIPT, 0, packet->systemAddress,

100 false); }

// Keep the stat from updating until the messages move to the thread or it quits right away nextStatTime=RakNet::GetTimeMS()+1000; }

if (packet->data[0] == 252) { //Recived message that all data has arrived to the client //Send over total data resent printf("Recived 252 Packet\n"); char * message = new char[5]; //int + 1 message[0] = (unsigned char)251; message[1] = (unsigned char)serverPacketLoss; server->Send(message, sizeof(message), LOW_PRIORITY, RELIABLE_ORDERED_WITH_ACK_RECEIPT, 0, packet->systemAddress, false); printf("Sent 251 Packet\n"); }

if (packet->data[0]==ID_CONNECTION_LOST) printf("ID_CONNECTION_LOST from %s\n", packet->systemAddress.ToString()); else if (packet->data[0]==ID_DISCONNECTION_NOTIFICATION) printf("ID_DISCONNECTION_NOTIFICATION from %s\n", packet->systemAddress.ToString()); else if (packet->data[0]==ID_NEW_INCOMING_CONNECTION) printf("ID_NEW_INCOMING_CONNECTION from %s\n", packet->systemAddress.ToString()); else if (packet->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) printf("ID_CONNECTION_REQUEST_ACCEPTED from %s\n", packet->systemAddress.ToString()); }

if (kbhit()) { char ch=getch(); if (ch==’’) { printf("Sending medium priority message\n"); char t[1]; t[0]=(unsigned char) 254; server->Send(t, 1, MEDIUM_PRIORITY, RELIABLE_ORDERED, 1, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } if (ch==’q’) quit=true; } }

101 if (client) { packet = client->Receive(); while (packet) { if (packet->data[0]==ID_DOWNLOAD_PROGRESS) //For each packet that are sent { //RakNet::BitStream progressBS(packet->data, packet->length, false); //progressBS.IgnoreBits(8); // ID_DOWNLOAD_PROGRESS //unsigned int progress; //unsigned int total; //unsigned int partLength;

//// Disable endian swapping on reading this, as it’s generated locally in ReliabilityLayer.cpp //progressBS.ReadBits( (unsigned char* ) &progress, BYTES_TO_BITS(sizeof(progress)), true ); //progressBS.ReadBits( (unsigned char* ) &total, BYTES_TO_BITS(sizeof(total)), true ); //progressBS.ReadBits( (unsigned char* ) &partLength, BYTES_TO_BITS(sizeof(partLength)), true ); // // //printf("Progress: msgID=%i Progress %i/%i Partsize=%i TotalData:%d\n", // (unsigned char) packet->data[0], // progress, // total, // partLength, // totalDatarecived);

} else if (packet->data[0]==255) { if (packet->length!=BIG_PACKET_SIZE) { printf("Test failed. %i bytes (wrong number of bytes).\n", packet->length); quit=true; break; }

/* if (BIG_PACKET_SIZE<=100000) { for (int i=0; i < BIG_PACKET_SIZE; i++) { if (packet->data[i]!=255-(i&255)) { printf("Test failed. %i bytes (bad data).\n", packet->length);

102 quit=true; break; } } } */

if (!quit) { printf("Test succeeded. %i bytes.\n", packet->length); totalDatarecived += (int)packet->length; bool repeat=false; if (repeat) { printf("Rerequesting send.\n"); unsigned char ch=(unsigned char) 253; client->Send((const char*) &ch, 1, MEDIUM_PRIORITY, RELIABLE_ORDERED, 1, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } else { if (totalDatarecived >= GB) { unsigned char ch = (unsigned char)252; //Transfer Completed client->Send((const char*)&ch, 1, MEDIUM_PRIORITY, RELIABLE_ORDERED, 1, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); stop = RakNet::GetTimeMS();

}

} }

} else if (packet->data[0]==254) { printf("Got high priority message.\n"); } else if (packet->data[0] == 251) { printf("Recived 251 Packet\n"); memcpy(&serverPacketLoss, &packet->data[1], sizeof(float)); quit = true; break; } else if (packet->data[0]==ID_CONNECTION_LOST) printf("ID_CONNECTION_LOST from %s\n", packet->systemAddress.ToString()); else if (packet->data[0]==ID_DISCONNECTION_NOTIFICATION)

103 printf("ID_DISCONNECTION_NOTIFICATION from %s\n", packet->systemAddress.ToString()); else if (packet->data[0]==ID_NEW_INCOMING_CONNECTION) printf("ID_NEW_INCOMING_CONNECTION from %s\n", packet->systemAddress.ToString()); else if (packet->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { start=RakNet::GetTimeMS(); printf("ID_CONNECTION_REQUEST_ACCEPTED from %s\n", packet->systemAddress.ToString()); } else if (packet->data[0]==ID_CONNECTION_ATTEMPT_FAILED) printf("ID_CONNECTION_ATTEMPT_FAILED from %s\n", packet->systemAddress.ToString());

client->DeallocatePacket(packet); packet = client->Receive(); } }

//if (RakNet::GetTimeMS() > nextStatTime) //{ // nextStatTime=RakNet::GetTimeMS()+1000; // RakNetStatistics rssSender; // RakNetStatistics rssReceiver; // if (server) // { // unsigned int i; // unsigned short numSystems; // server->GetConnectionList(0,&numSystems); // if (numSystems>0) // { // for (i=0; i < numSystems; i++) // { // server->GetStatistics(server->GetSystemAddressFromIndex(i), &rssSender); // StatisticsToString(&rssSender, text,2); // printf("==== System %i ====\n", i+1); // printf("%s\n\n", text);

// } // } // } // if (client && server==0 && client->GetGUIDFromIndex(0)!=UNASSIGNED_RAKNET_GUID) // { // client->GetStatistics(client->GetSystemAddressFromIndex(0), &rssReceiver); // StatisticsToString(&rssReceiver, text,2); // printf("%s\n\n", text); // }

104 //}

RakSleep(100); }

double ms = (double)(stop-start);

if (server) { RakNetStatistics *rssSender2=server->GetStatistics(server->GetSystemAddressFromIndex(0)); StatisticsToString(rssSender2, text, 1); printf("%s", text); }

std::string filename = "RaknetLog"; //filename.append((char*)BIG_PACKET_SIZE);

file.open(filename + ".tsv"); file << filename << "\n"; file << "Packet Size: " << BIG_PACKET_SIZE << " B\n"; file << "Time (ms) Loss\n"; file << ms << "" << serverPacketLoss << "\n"; file.close();

printf("%i bytes per ms (%.2f ms), Average Packet Loss: %d. Press enter to quit\n",(int)((double)(BIG_PACKET_SIZE) / ms), ms, serverPacketLoss) ; Gets(text,BIG_PACKET_SIZE);

delete []text; RakNet::RakPeerInterface::DestroyInstance(client); RakNet::RakPeerInterface::DestroyInstance(server);

return 0; }

105 Appendix C

Hardware List and Network settings

Computer(s): CPU: Intel Core i5-5250U CPU @ 1.60GHz RAM: 16GB OS: Windows 10 64-bit

Ethernet Cabels: 1 Gigabit/s cables

Switch: Model: NETGEAR ProSAFE PlusSwitch GS105E

Router: Model: RT-N56U Dual-band Wireless-N Gigabit Router

Router Network: SSID: ASUS Protocol: 802.11n Security type: Open Network band: 2.4 GHz Network channel: 2 IPv4 address: 192.168.1.27 IPv4 DNS Servers: 192.168.1.1 Manufacturer: Intel Corporation Description: Intel(R) Dual Band Wireless-AC 7265 Driver version: 19.1.0.4 Physical address (MAC): ?00-21-5C-B9-10-90

Eduroam: SSID: eduroam Protocol: 802.11a Security type: WPA2-Enterprise Type of sign-in info: Microsoft: Protected EAP (PEAP) Network band: 5 GHz Network channel: 36 IPv6 address: 2001:6b0:2a:c280:1128:9cbe:b9ef:8544 IPv4 address: 193.11.185.53 IPv4 DNS Servers: 10.241.1.10

106 Primary DNS suffix: eduroam.bth.se Manufacturer: Intel Corporation Description: Intel(R) Dual Band Wireless-AC 7265 Driver version: 19.1.0.4 Physical address (MAC): ?00-21-5C-B9-10-90

107 Appendix D

Literature study

108 Criteria for inclusion will be, in order: 1. Title seems relevant 2. Abstract seems relevant 3. The papers is read and is deemed relevant by the author

Search terms: TCP, Transmision Control Protocol, UDP, User Datagram Protocol, Performance, Network Protocols, comparison, measurment

Index: Title: Author/s: 1 Performance analysis of computer Sadiku, M.N.O., networks Musa, S.M.

2 TCP and UDP Performance over a George Xylomenos,. Wireless LAN George C. Polyzos

3 Improving Round-Trip Time Estimates Phil Karn in Reliable Transport Protocols Craig Partridge (1995)

4 A COMPARATIVE ANALYSIS OF Muhammad Ajmal Azad, DCCP VARIANTS (CCID2, CCID3), Rashid Mahmood, TCP AND UDP FOR MPEG4 VIDEO Tahir Mehmood APPLICATIONS

109 Performance analysis of computer networks Refrences Ref nummber: Title: Author/s: 55 A Queueing Model with Finite Waiting Room and Authors of DocumentKonheim, Blocking A.G., Reiser, M. 141 End-to-end performance of interconnected LANs Berg, B., H Deng, R.

Citations Ref nummber: Title: Author/s: Nan

TCP and UDP Performance over a Wireless LAN Refrences Ref nummber: Title: Author/s: 1 IEEE 802.1 I wireless local area networks B.P. Crow, I. Widjaja, J. Geun Kim, and P.T. Sakai, 2 A comparison of mechanisms for improving TCP H. Balakrishnan, V.N. performance over wireless links Padmanabhan, S. Seshan, and R.H. Katz 3 evelopment of WaveLAN, an ISM band wireless LAN B. Tuch 4 Measured performance of a wire- less LAN D. Duchamp and N.F. Reynolds 5 Measurement and analysis of the error D. Eckhardt and P. Steenkiste characteristics of an in-building wireless network 6 A trace- based approach for modeling wireless G.T. Nguyen, R.H. Katz, B. channel behavior Noble, and M. Satyanarayanan, 7 CP slow start. congestion avoidance, fast retransmit, W. Stevens and fast recovery algorithms 8 imulation-based comparisons of Tahoe, Reno and K. Fall and S. Floyd SACK TCP 9 Throughput performance of transport-layer protocols A. DeSimone, M.C. Chuah. and over wireless LANs O.C. Yue 10 TCP and explicit congestion notification, S. Floyd

Citations Ref nummber: Title: Author/s: 1 Cross-Layer Analysis of Rate Adaptation DCF and J. Choi, K. Park, C.-k. Kim TCP in Multi-Rate WLANs 2 Virtual Web channel: flow aggregation for enhanced S. Giordano, D. Lenzarini, M. ubiquitous Web access Schiavoni, S. Vanini 3 Reliable User Datagram Protocol for airborne Tuong Le, Giri Kuthethoor, network Chokchai Hansupichon, Prakash Sesha, John Strohm, Gregory Hadynski, Diane Kiwior, David Parker 4 Real time transmission of MPEG2 video over 802.11 I. Izzat, M. Mayer, R. Rhodes, T. a wireless LANs Stahl 5 Wireless IP adaptation layer: an open performance P. Mahonen, L. Munoz, D. enhancement protocol architecture Melpignano, G. Orphanos, Z. Shelby, T. Saarinen, M. Garcia 110 6 Suitability of wireless solutions for large bandwidth Matteo Codda, Andrea Mariscotti sensors interconnection 7 Throughput Analysis and Measurements in IEEE Raffaele Bruno, Marco Conti, 802.11 WLANs with TCP and UDP Traffic Flows Enrico Gregori 8 Sniffing out the correct physical layer capture model A. Kochut, A. Vasan, A.U. in 802.11b Shankar, A. Agrawala 9 Improving performance of rate control mechanism Hrishikesh Sharma, Aditya Sood, for UDP traffic over heterogeneous networks P. Balamuralidhar 10 IEEE 802.11 wireless LAN security performance N. Baghaei, R. Hunt using multiple clients 11 H2O clouds: issues challenges and solutions S. Ghandeharizadeh 12 Optimizing Internet flows over IEEE 802.11b L. Munoz, M. Garcia, J. Choque, wireless local area networks: a performance- R. Aguero, P. Mahonen enhancing proxy based on forward error correction 13 Current trends and challenges towards wireless C. Basios, M. Solidakis Internet 14 Improving thoughput and fairness of transport S. Malik, M. Jaseemuddin, G. connections in IEEE 802.11 based wireless networks Ravindram, H. El-Sayed 15 Enhancing mobile collaboration with HLMP Juan Rodríguez-Covili, Sergio F. Ochoa, José A. Pino 16 Testing large scale streaming Internet applications P. Ikkurthy, J. Shahbazian, M.A. over wireless LANs Labrador, K.J. Christensen 17 Performance Evaluation of IEEE 802.11 Xiaowen Chu, Yong Yan Infrastructure Mode with Intra-Cell UDP Traffic 18 A wireless multimedia LAN testbed Jinsong Wu, J. Ilow 19 support for quality of service on wireless G. Xylomenos, G.C. Polyzos Internet links 20 Efficiency and fairness trade-off for TCP over UMTS- A. Baiocchi, F. Cuomo TDD 21 Analysis of Network Throughput Dynamics with Hiroshi Yoshida, Kousuke Viscoelastic Material Model Nogami, Kozo Satoda 22 Performance impact of interlayer dependence in Sunwoong Choi, Kihong Park, infrastructure WLANs Chong-kwon Kim 23 Experimental evaluation of a wireless ad hoc S. Desilva, S.R. Das network 24 A reliable multicast protocol for distributed mobile G. Anastasi, A. Bartoli, F. systems: design and evaluation Spadoni 25 Experimenting With Commodity 802.11 Hardware: Pablo Serrano, Pablo Salvador, Overview and Future Directions Vincenzo Mancuso, Yan Grunenberger 26 Operational and fairness issues with connection-less T. Pagtzis, P. Kirstein, S. Hailes traffic over IEEE802.11b 27 Experimental controller tuning and QoS optimization A. Panousopoulou, G. of a wireless transmission scheme for real-time Nikolapoulos, A. Tzes remote control applications 28 Measurement of TCP and UDP performance over Fumie Ono, Kenichi Takizawa, UAS relay networks Hiroyuki Tsuji, Lin Shan, Toshinori Kagawa, Ryu Miura 29 Channel state awareness based transmission power J.P. Singh, Yan Li, N. Bambos adaptation for efficient TCP dynamics in wireless networks 30 Robust routing and Multi-Confirmation Transmission James Stephan, Jonathan Fink, Protocol for connectivity management of mobile Benjamin Charrow, Alejandro robotic teams Ribeiro, Vijay Kumar 31 DOMINO: Detecting MAC Layer Greedy Behavior in M. Raya, I. Aad, J.-P. Hubaux, IEEE 802.11 Hotspots A. El Fawal 111 32 Analysis of Cross-Layer Interaction in Multirate Jaehyuk Choi, Kihong Park, 802.11 WLANs Chong-kwon Kim 33 Systematic Performance Modeling and A. Botta, D. Emma, A. Pescape, Characterization of Heterogeneous IP Networks G. Ventre 34 A bidirectional data transfer protocol for capacity and Dong-Hee Kwon, Woo-Jae Kim, throughput enhancements in multi-rate wireless Young-Joo Suh LANs 35 Mobile agents for routing topology discovery and N. Migas, W.J. Buchanan, K.A. automatic network reconfiguration in ad-hoc McArtney networks 36 Wireless VPNs: an evaluation of QoS metrics and K.S. Munasinghe, S.A. measures Shahrestani 37 Measuring the QoS Characteristics of Operational Simone Ferlin, Thomas 3G Mobile Broadband Networks Dreibholz, Ozgu Alay, Amund Kvalbein 38 Wireless Internet over LMDS: architecture and P. Mahonen, T. Saarinen, Z. experimental implementation Shelby, L. Munoz 39 Map update application: Performance D. Astudillo, E. Chaput, A. Beylot measurements on a highway scenario 40 Evaluation of reliable UDP-based transport protocols Madzirin Masirap, Mohd Harith for Internet of Things (IoT) Amaran, Yusnani Mohd Yussoff, Ruhani Ab Rahman, Habibah Hashim 41 Cross-Layer Measurements for a Comprehensive Leopoldo Angrisani, Michele Characterization of Wireless Networks in the Vadursi Presence of Interference 42 Improved performance of UDP & TCP throughput in P. Venkat Ramana, S. Narayana Wi-Fi networks for voice and data services in mobile Reddy communications with MIMO systems 43 Performance Assessment of Wireless Leopoldo Angrisani, Michele Communication Networks through Cross-Layer Vadursi Measurements 44 In-home online entertainment: analyzing the impact C.E. Palazzi, G. Pau, M. of the wireless MAC-transport protocols interference Roccetti, M. Gerla 45 Fast connect procedure for Session Initiation Vineet Menon, S. V. Kulgod, Protocol using cached credentials Jagadeesh Bangalore 46 Optimal placement of multiple 802.11B APS in a Zhigang Jin, Xiuli Wu, Yantai wireless classroom Shu, Fang Liu 47 On latency in IEEE 802.11-based wireless ad-hoc Oliver Wellnitz, Lars Wolf networks 48 Internet protocol performance over networks with G. Xylomenos, G.C. Polyzos wireless links 49 A measurement study on 802.11 concurrently used Thomas King, Thomas for positioning and communications Haenselmann, Stephan Kopf, Wolfgang Effelsberg 50 Analysis of wireless message broadcast in large ad P. Poupyrev, A. Kosuga, P. hoc networks of PDAs Davis 51 Desktop presentation tool for e-learning support and Michal Kokorceny, Agata the high-speed UDP datagram loss Bodnarova 52 A Reconfigurable Transmission Scheme for Lossy George Nikolakopoulos, Image Transmission over Congested Wireless Nikolaos Fanakis Sensor Networks 53 Behavior of UDP-based applications over IEEE M.G. Arranz, R. Aguero, L. 802.11 wireless networks Munoz, P. Mahonen 54 TCP performance issues over wireless links G. Xylomenos, G.C. Polyzos, P. Mahonen, M. Saaranen 112 55 Performance of reliable transport protocol over IEEE Haitao Wu, Yong Peng, Keping 802.11 wireless LAN: analysis and enhancement Long, Shiduan Cheng, Jian Ma 56 Modeling and Simulation of Computer Networks and Francisco J. Suárez, Pelayo Systems Nuño, Juan C. Granda, Daniel F. García 57 58 Swan Highly Reliable and Efficient Networks of True Andrija Bosnjakovic, Virgil Peers Bourassa, Fred Holt, Jovan Popovic 59 Telecommunications apparatus and method, storage Nakano, Takehiko medium, and program 60 Telecommunications apparatus and method, storage Nakano, Takehiko medium, and program 61 Method and system to model TCP throughput, Scharf-Katz, Volkmar; Singh, assess power control measures, and compensate for Jatinder Pal; Bambos, Nicholas fading and path loss, for highly mobile broadband systems 62 TELECOMMUNICATIONS APPARATUS AND Nakano, Takehiko METHOD STORAGE MEDIUM AND PROGRAM 63 COMMUNICATION DEVICE COMMUNICATION Nakano, Takehiko METHOD RECORDING MEDIUM AND PROGRAM 64 WIRELESS LOCAL ACCESS NETWORK TEST PRAT, Florent; FARGUE, DEVICE Vincent 65 WIRELESS LOCAL ACCESS NETWORK TEST PRAT, Florent; FARGUE, DEVICE Vincent

Improving Round-Trip Time Estimates in Reliable Transport Protocols Refrences Ref nummber: Title: Author/s: 1 Selective Acknowledgments in TCP Braden, Robert T 2 NEI’BLT: A Bulk Data Transfer Proto- col; RFC998 Clark, David D., Lambert, Mark L., and Zhang, Lixia 3 An Adaptive Timeout Algorithm for Retransmission Edge, Stephen William. Across a Packet Switching Network 4 Version 2 of the Reliable Data Protocol Hinden, Robert M. and Partridge, Craig 5 Connection oriented transport protocol specification International Organization for Standards, Infor- mation processing systems - Open Systems Interconnection 6 Presentation to the Internet End-To-End Services Jacobson, Van Task Force 7 Interpacket Arrival Variance and Mean Jacobson, Van 8 Retransmit Timers: Theory and Practice Jacobson, Van 9 Divergence of Timeout Algorithms for Packet Jain, Raj Retransmission 10 Radio in the Amateur Service Kam, P. R., Price, H., Diersing, R. Packe 11 Internet Delay Experiments; RFC889 Mills, David 12 Algorithms for Synchronizing Network Clocks; Mills, David RFC956 13 Experiments in Network Clock Synchronization; Mills, David RFC957 14 ; RFC958 Mills, David 113 15 Fixing timeout intervals for lost packet detection in Morris, Robert J.T computer communication networks 16 Congestion Control in IP/TCP Networks; RFC896 Nagle, John 17 Implementing the Reliable Data Protocol (RDP) Partridge, Craig 18 Congestion in the ARPANET Perry, Dennis G 19 Internet Protocol; RFC791 Pastel, J., ed 20 Internet Control Message Proto- col; RFC792 Postel, J., ed 21 Transmission Control Protocol; RFC793 Postel, Jon, ed 22 Reliable Data Protocol; RFC908 Velten, David, Hinden, Robert and Sax, Jack 23 Timer-Based Mechanisms in Reliable Transport Watson, Richard W Protocol Connection Management 24 Why TCP Timers Don’t Work Well Zhang, Lixia

Citations Ref nummber: Title: Author/s: 1 Ken Carlberg , Panos Gevros , Lower than best effort: a design and implementation Jon Crowcroft 2 Internet service differentiation using transport Panos Gevros options: the case for policy-aware congestion control 3 On the use of a full information feedback to stabilize Shahram Jamali , Seyyed RED Nasser Seyyed Hashemi , Amir Masoud Eftekhari Moghadam 4 SpeedDetect: a simple TCP extension for handling Gergely Biczók , Gábor Németh , sudden capacity increase Péter Tarján , Ferenc Kubinszky , András Veres 5 Evaluating the adaptivity of computing systems Philipp Reinecke , Katinka Wolter , Aad van Moorsel 6 Design and analysis of a self-tuning feedback Naixue Xiong , Yi Pan , Xiaohua controller for the Internet Jia , Jong Hyuk Park , Yingshu Li 7 A novel self-tuning feedback controller for active Naixue Xiong , Athanasios V. queue management supporting TCP flows Vasilakos , Laurence T. Yang , Cheng-Xiang Wang , Rajgopal Kannan , Chin-Chen Chang , Yi Pan

A COMPARATIVE ANALYSIS OF DCCP VARIANTS (CCID2, CCID3), TCP AND UDP FOR MPEG4 VIDEO APPLICATIONS Refrences Ref nummber: Title: Author/s: 1 User Datagram Protocol J. Postel 2 Transmission Control Protocol J. Postel 3 Datagram Congestion Control Protocol (DCCP) E. Kohler, M. Handley and S. Floyd 4 Profile for Datagram Congestion Control Protocol E. Kohler and S. Floyd (DCCP) Congestion Control ID 2: TCP-like Congestion Control 5 Profile for Datagram Congestion Control Protocol S. Floyd, E. Kohler and J. (DCCP) Congestion Control ID 3: TCP-Friendly Rate Padhye Control (TFRC) 6 TCP Friendly Rate Control (TFRC): Protocol M. Handley, S. Floyd, J. Padhye Specification. and J. Widmer (2008) 114 7 Nwtwork Simulator Tool (NS-2) http://www.isi. edu/nsnam/ns/index.html 8 A DCCP module for ns-2 Nils-Erik Mattson 9 Selective Frame Discard for Video Streaming over IP Ricardo N. Vaz1 and Mario S. Networks Nunes 10 A performance comparison study of DCCP and a Arne Lie, Ole Morten Aamo, and method with non-binary congestion metricsfor Leif Arne Rønningen streaming media rate control 11 Performance Evaluations of DCCP for Bursty Traffic Shigeki Takeuchi, Hiroyuki Koga, in Real-time Applications Katsuyoshi Iida, Youki Kadobayashi and Suguru Yamaguchi 12 RTP and the Datagram Congestion Control Protocol Colin Perkins and Ladan Gharai 13 Performance of Constant Quality Video Applications J. Van Velthoven, K. Spaey and using the DCCP Transport Protocol C. Blondia 14 Video quality estimation of DCCP streaming over Sebastien Linck, Emmanuel wireless networks Mory, Julien Bourgeois, Eugen Dedu and Francois Spies 15 On the Performance of DCCP in Wireless Mesh P. Navaratnam, N. Akhtar and R. Networks Tafazolli 16 Multimedia Congestion Control for Broadband Arjuna Sathiaseelan and Gorry Wireless Networks Fairhurst 17 Performance of VoIP using DCCP over a DVB-RCS Arjuna Sathiaseelan and Gorry Satellite Network Fairhurst 18 An Experimental Evaluation of Voice Quality over the Horia Vlad Balan, Lars Eggert, Datagram Congestion Control Protocol Saverio Niccolini and Marcus Brunner 19 Performance Evaluation of DCCP and SCTP for Sumera Nosheen, Dr.Shahzad MPEG4 Video over Wireless Networks A. Malik, Yousaf Bin Zikria and Muhammad Khalil Afzal 20 A Comparative Performance Evaluation of DCCP Saleem Bhatti, Martin Bateman and Dimitris Miras 21 On the Performance of TCP, UDP and DCCP over Leandro Melo de Sales, Hyggo 802.11g Networks O. Almeida and Angelo Perkusich 22 Video streaming over wireless DCCP Burak Gorkemli, M. Oguz Sunay and A. Murat Tekalp 23 RTP Payload Format for Transport of MPEG-4 J. van der Meer, D. Mackie, V. Elementary Streams Swaminathan, D. Singer and P. Gentric

Citations Ref nummber: Title: Author/s: 1 Bandwidth aggregation in heterogeneous wireless AL Ramaboli, OE Falowo, AH networks: A survey of current approaches and Chan issues 2 A general texture mapping framework for image- L Xu, E Li, J Li, Y Chen, Y Zhang based 3d modeling 3 Adaptation strategies for streaming SVC video B Görkemli, AM Tekalp 4 Multipath Transmission for Wireless Internet W Zhuang, N Mohammadizadeh, Access--From an End-to-End Transport Layer S Shen Perspective 5 Adaptation strategies for MGS scalable video B Görkemli, AM Tekalp streaming

115 6 Friendliness of DCCP towards TCP over large delay SA Nor, S Hassan, O Ghazali link networks 7 Simulation Based Comparison of SCTP, DCCP and MN Khalid UDP Using MPEG-4 Traffic Over Mobile WiMAX/IEEE 802.16 e 8 Exploration of RTP circuit breaker with applications N Fough, F Verdicchio, G to video streaming Fairhurst 9 Efficient Packetization for DCCP Flows over ARQ- Chi-Huang Shih, Chih-Heng Ke, based Wireless Networks Yeong-Yuh Xu 10 The performance of DCCP TCP-like with initial slow- S Awang Nor, S Hassan, O start threshold manipulation Ghazali, MH Omar 11 Comparative study of Congestion Control Technique Sahrul Hilmi Ibrahim, Yuki in High Speed Network Matsuzawa, Noor M. Asraf, Salahuddin Ali, Siti Aufa, Jalil Md Desa 12 Concurrent multipath transmission to improve AL Ramaboli performance for multi-homed devices in heterogeneous networks 13 Synchronization of streamed audio between multiple C Lauri, J Malmgren playback devices over an unmanaged IP network 14 Performance Analysis of the Datagram Congestion SC Jero Control Protocol DCCP for Real-Time Streaming Media Applications 15 Improved Protocol for Secondary H Xu, W Wu, T Zhang, D Wang Users' Informatioin Exchanges in a Cognitive Radio 16 Performance Evaluation of TCP and DCCP A Khan, A Almagrabi, S Ahmad, Protocols in Mobile Ad-Hoc Networks (MANETS) SA Khan 17 Synchronization of streamed audio between multiple J Malmgren, C Lauri playback devices over an unmanaged IP network 18 Proportional Cram of Congestion ControlTechnique S Uma, TL Narayanan in High Fastness Network 19 Performance evaluation of TCP, UDP and DCCP for WA Kamil video traffics over 4G network 20 Performance analysis of real time media application Sahrul Hilmi Ibrahim, Sevia M. in OpenFlow network Idrus, Nadiatulhuda Zulkifli 21 Pushing Boundaries of User-Empowered Network- P Holub Centric Collaborative Environments 22 A family of QoS-aware traffic control protocols L Ye 23 Simulation-based Performance of Transport WA Kamil, R Alubady, SA Nor Protocols Using MPEG-4 Traffics over 4G Network

116