Fountain Multimedia Broadcasting - Walter Scott, Jr....

21
Fountain Multimedia Broadcasting Final Report Spring Semester 2012 -Full Report- By Aqeel Alhashim Ben Kappel Jassim Alhashim Prepared to partially fulfill the requirements for ECE402 Department of Electrical and Computer Engineering Colorado State University Fort Collins, Colorado 80523 Project advisor: Dr. J Rockey Lou

Transcript of Fountain Multimedia Broadcasting - Walter Scott, Jr....

Fountain Multimedia Broadcasting Final Report

Spring Semester 2012

-Full Report-

By Aqeel Alhashim

Ben Kappel Jassim Alhashim

Prepared to partially fulfill the requirements for ECE402

Department of Electrical and Computer Engineering

Colorado State University Fort Collins, Colorado 80523

Project advisor: Dr. J Rockey Lou

ii

Abstract

Multimedia broadcasting has recently become a major topic as digital media demand has increased. As network speeds increase we will continue to see a move towards more efficient digital multimedia broadcasting methods. Current multimedia streaming methods are very inefficient using UDP with complex error correction coding, and TCP with an acknowledgement signal. Our hypothesis is that fountain coding can be shown to improve speed, efficiency, and increase the number of simultaneous clients streaming from a multimedia source. By coding and testing fountain coding algorithms we will be able to accurately test this hypothesis against current error correction algorithms.

The objective of this project is to use fountain-broadcasting algorithm for streaming media to achieve higher speeds and improved efficiency compared to the current retransmission scheme and forward error correction methods. Our first stage was to make a multimedia streaming application with the proper feedback that would be required for our transmission and error correction algorithms. Our two media streaming programs consisted of; UDP with selective TCP feedback, and traditional TCP with feedback. Our primary focuses were learning network programming, designing and implementing a streaming media application, and researching streaming media transmission and error correction methods.

Our current application uses UDP to stream media while providing selective TCP feedback to be used with the fountain code algorithm implemented in the future. Future research focus will be on reducing latency gain for large multicast loads by implementing and testing the fountain code algorithm. Overall there was an increase in latency for an increase in clients for the traditional TCP method. This project will be continued next semester.

iii

TABLE OF CONTENTS Title i

Abstract ii

Table of Contents iii

List of Figures and Tables iv

I. Introduction 1

II. Previous and Current Multimedia Stream Methods 3

III. Previous Studies of Fountain Code 5

IV. Summary of Current Work 7

V. Ethical Issues 8

VI. Future Work 9

VII. Conclusion 10

References 11

Appendix A - Abbreviations 12

Appendix B – Budget 13

Appendix C – Code 14

iv

LIST OF FIGURES

Figure 1 - TCP/IP packet transmission 3

Figure 2 - UDP with forward error correction code 4

Figure 3 - Example of Fountain Code 5

Figure 4: Example of Fountain Code Encoding/Decoding Equations 6

1

Chapter I: Introduction

Multimedia broadcasting, in the past few years, has seen a drastic increase in demand by everyday consumers. A study done by the Pew Research Center in 2010 showed that seven in ten Internet users have used the Internet for downloading or streaming video. It is also obvious that video uploads are popular. The website YouTube is one of the largest sources of user shared media and is increasing in users that download and upload everyday.

Multimedia broadcasting has also seen an increase in digital multimedia subscription services. Services such as Netflix, Hulu, Comcast, and Blockbuster have increased the demand for streaming movies to a client’s home. This move towards a “digital rental service” has increased the amount of data that is transferred over networks. Current protocol methods such as user datagram protocol and transmission control protocol are the most commonly used, and each has their advantages and disadvantages. TCP/IP has an acknowledgement packet to ensure error free transmissions, but is slow. Major issues for TCP transmission of media are:

- Requires packet retransmission so long as any receiver does not receive the packet.

- Requires feedback for every packet. - High latency in multicast applications with a large number of clients.

An alternative to gain speed is UDP, but UDP is also very unreliable and requires complex code to be effective in media streaming applications. The major problems of UDP to stream multimedia are:

- Fixed redundancy rate irrespective of the channel condition. - Unnecessary redundancy if the channel is good. - Transmission failure if packet erasure rate exceeds expectation.

Fountain coding uses user datagram protocol combined with an error correction algorithm that is purely decoded on the receiver side. This uses the speed of UDP mixed with a high reliability to reduce the problems with common UDP and TCP/IP protocols. Some of the major of advancements that fountain coding provide are:

- Rate-less transmission, the server sends out encoded packets in any order, and the receivers can decode the data from the given set.

- No retransmission of lost packets, just needs to receive more packets to decode.

- Selective feedback. - Adaptability between bad and good channel quality.

Our goal to initialize this project was to create the programs needed to test fountain code algorithms by researching network programming, research multimedia streaming, and produce a final product to be tested. Our primary goals of this part of the project are to create a couple of multimedia streaming programs. We will need various programs to test the fountain code, and some other programs to be able to compare fountain code to other coding algorithms.

We have created two multimedia streaming programs one using TCP with the traditional feedback, and a second using UDP to test fountain coding. The first program is

2

adaptable to multiple clients determined at run time. This program also has some sort of measurement of the total latency taken as a function of the number of clients currently streaming the media. Latency measurement is essential to show better performance of a particular method of streaming. The second program is aimed at testing fountain code. Fountain code requires a fast downlink combined with a selective and reliable feedback. For this program we used UDP to send the multimedia stream and TCP to provide a reliable feedback mechanism. We also have a method to ensure that the feedback is selective. These two programs are described in detail in Chapter IV. The second and main goal of this overall project is to test a proprietary fountain algorithm against traditional methods of streaming media. This is essential as a continuation of this project and will be the main focus of the final results. For this half of the project it was required to gain an understanding of how this fountain code will work to guarantee that the multimedia program that is created will be applicable to test fountain code. Our knowledge of fountain code is explained in Chapter III.

3

Chapter II: Previous and Current Multimedia Streaming Methods

Current network protocols work correctly, however there are some problems that need to be addressed as data transfer size is growing and the number of clients receiving the data is increasing as well. We currently have two major methods of streaming video:

- User Datagram Protocol (UDP) - Transmission Control Protocol (TCP)

Both of these methods are currently used for different types of applications. First we will discuss TCP/IP and some applications that use this type of network transmission. TCP/IP applications include, but are not limited to:

- E-Mail - Internet Browsers - Computer IP addresses

TCP/IP is a great protocol for reliability. It uses an acknowledgement signal from the receiver back to the sender to confirm that every packet has been received before sending the next packet in line. While very efficient for small files, it the server is sending large files and the network has a high error probability this will slow the transfer speed significantly. Below in Figure 1 we can see a basic picture of how the TCP/IP protocol sends and receives packets.

Figure 1: TCP/IP packet transmission

TCP when used for multicast multimedia streaming has major issues. If we have a number of clients, and one TCP multimedia server using acknowledgement signals to retransmit any lost packets, the server will eventually reach a maximum number of clients that can be effectively transmitted data. All network links have a probability for error due to unreliable routing schemes and other inconsistencies, and TCP is effective for 100% guaranteed transmission. However as the number of clients increase the total retransmission due to errors increases. If the amount of retransmission surpasses the amount of data sent successfully then no clients will receive original data and multimedia transmission will cease. This is a major problem with using TCP to stream multimedia to

4

multiple clients. Fountain code as explained in Chapter IV solves this major problem, while still providing a 100% guarantee of decoding original data at the receiving end.

The second major type of network transmission protocol is the user datagram protocol or UDP for short. UDP is typically used where speed is essential. This method of sending data will not wait for an acknowledgement signal back and will keep sending packets regardless of whether the receiver has actually received them. Current methods of using UDP often use an extra error correction code attached to each packet so that the receiver can decode the original data if a packet is lost in transmission. Figure 2 below shows a method of attaching error correction code to a UDP packet. This method is called forward error correction or FEC for short.

Figure 2: UDP with forward error correction code

While this method of forward error correction eliminates the problem of reliability with UDP, it has a downside. The problem with UDP with FEC is that there is a high amount of redundancy. We can see above in Figure 2 that each packet has an error correction code added to the original data to allow the receiver to correct any missing packets. This turns a small file transfer into a much larger one and increases latency of this packet on the network. Another major problem with forward error correction coding schemes is a fixed redundancy rate. When using forward error correction an algorithm is specified for a maximum error that will be seen by the channel. Using forward error correction it is guaranteed that anything less then this predicted channel error would provide 100% guaranteed decoding of original packets on the receiving end. By providing encoding of original data for a maximum channel error rate, the overhead of encoding is fixed. If a channel consistently provides a lower error rate than was predicted, overhead latency is wasted. If a channel has a higher error rate than was predicted, then the forward error correction fails and the receiver cannot decode original data.

5

Chapter III: Previous Studies of Fountain Code Fountain code is a type of error correction algorithm using UDP transmission protocol. Few studies have been done about this type of error correction, as it is relatively new. Fountain code is a way to correct packet loss over a network. The basic theory behind this code is that it takes in packets of source data, encodes this data into an infinite number of packets. The server then sends out these packets randomly to a receiver or multiple receivers. The receiving end gathers as many packets as it needs to decode back to the original source data. The number of packets needed to decode the encoded data on the receiver side is larger then the original amount of packets, so a feedback transmission is needed to let the server know when to send more encoded packets. Shown below in Figure 3 is a basic diagram that explains, at a higher level, a basic form of fountain code.

Figure 3: Example of Fountain Code

From a paper (MacKay) written in 2005, there are three main types of fountain code:

- Random Linear Fountain - LT Code - Raptor Code

From these three types of code, Raptor code is the most efficient. Raptor code uses two types of LT code to make the fountain code more efficient. All of these codes use a generating matrix to encode the original source data. From this on the receiving end the received encoded packets can be combined with the inverse of the generating matrix to decode the original source data. Common fountain code encoding and decoding uses an algorithm based off of a bitwise sum, modulo 2. This can also be seen as an algorithm based off of a bitwise exclusive or, Boolean function. Another major type of fountain code that is presented is random linear fountain code. This code takes the original data packets and encodes them with an encoding function that can be represented by the equation below. Similarly on the receiving end the encoded packets that have been received without error can be decoded by using the equation shown below. To encode the original data the transmitted packet is set to a bitwise sum, modulo2 of the source packets for which Gnk is 1. On the receiving end the original packet can be decoded using the inverse of this matrix.

6

Figure 4: Example of Fountain Code Encoding/Decoding Equations

The above equations have two unlisted variables G. Radom linear fountain code

uses a random generating matrix where a set of bits, K define each column of this matrix. The generating matrix G can then be created using any assortment of numbers; an example could be a deterministic random number generator. In this example the random number generator decoding the data on the receiving end is required to be synchronized to the senders encoding matrix in order to successfully decode the original data. A requirement of random linear fountain code is that that the number of received packets be larger than the number of original packets used to encode the data. In this case it would require that the number of received packets, N, be larger than the number of original packets encoded in the algorithm, K. If the number of packets N is less than K then the receiving end will be unable to decode the original data. This is when the feedback TCP signal will be used. It will request for more packets to be sent from the server. If N=K the receiver should be able to decode the original data, but for consistency often it is required that N>K. Next semester will be dedicated to testing a proprietary algorithm for fountain code. Once successful the algorithm will provide a lower complexity of encoding and decoding the data. Current fountain code research is aimed at reducing the complexity of the algorithm. Raptor code and LT code provide lower complexity than random linear fountain code. As fountain code gains more research support we will se an increase in the number of streaming applications to use this method of erasure code.

7

Chapter IV: Summary of Current Work

The code we have designed includes two important parts. The first major part is streaming the video using UDP. UDP is used to provide the speed required in streaming media. By using an algorithm for fountain code, UDP can be very reliable. UDP is a fast way to send packets through the Internet since there is no connection made between the server and clients. It is also more efficient for sending to multiple clients at the same time. Part of our code is streaming video using UDP, which is provided by the server program. The server will be waiting for a request from a client to start streaming media to a client using what is called a fork() function. Fork() allows the server to stream video for more than one client simultaneously, while also allowing more connections to be made. The second part of our code is using a TCP connection. This kind of connection provides a reliable method of feedback, but at a cost of increasing the latency of the stream. We used TCP in the client to tell the server that client has enough packets or cannot decode the original data and needs more packets. The TCP connection is used as a single signal switch to pause or continue the server media stream. This on or off switch depends on whether a client can decode the original data successfully from the received data as explained in Chapter III. The sever source code provides three major functions. First, the server will be waiting to receive a request from any client to start streaming the video. When the server receives a request, it will create a process to take care of the requested client. When the process is created, it will start a media stream to that client. The server is also waiting for another request from any number of clients. In the client source code, the program will start receiving the stream and send the data to a media player when a specified buffer minimum is reached. When the client has enough packets to successfully decode the original data a signal will be sent to the server using TCP connection to tell it stop sending encoded packets. When the server receives this signal it will stop streaming the media while waiting for another signal to continue streaming. Once the client has successfully received all of the media, the server can terminate this process and continue to stream to other connected clients. This code can be found in Appendix C. Our second code was a basic TCP streaming server and client. This code was relatively easy to make, but we needed additions to add timing ability and overall latency calculations. All that was changed in this code from the previous code was the method of streaming media.

8

Chapter V: Ethical Issues The major ethical issues with any software release are in the functionality and implementation of the source code. Source code can be divided into a couple of categories including licensed, copyrighted, public domain, and illegal code. Licensed code usually contains rules that contain proper use information. Copyrighted code is free to use, but credit must be given to the author. Public domain code is free to use because it has no official author. Illegal code is code that is stolen from an application and released without the company’s knowledge.

Fortunately, our program uses all open source code with the built in libraries for C. The only section of our code that contains another application is the playback of the video, but essentially playback is not necessary for our final product release. Playback is only used in this project to confirm that our program is working correctly.

If we were to release a multimedia streaming application that uses our final proprietary algorithm we would have to add a couple of additions to our program. The first addition would have to be a custom made streaming method. This would take some research in how to playback video and create a player in C. We would also need to create a easy to use graphical user interface as our program runs from command line only, and most users would not prefer to run our program using this method.

The next ethical issue with our program involves ensuring that it has proper security, and no known flaws. When software is released to a user the company or seller has to guarantee that the information used is secure and that the program will not cause something to fault on their system. Currently our program has little to no safeguards. We are using it for research and testing. If we were to create a final product and release it, we would have to add error checking to our program, and possibly an encryption method to the data that is transferred. Adding these two things we would be able to confirm that our product is ethically safe for the user to use.

Our final ethical issue that could arise with the future implementation of the proprietary algorithm is patents or copyrights. If this was a major upgrade to current streaming multimedia methods, then CSU may want to hold a right to the algorithm. Also the research findings paper must be accurate and have many test cases. If this paper does not test all the cases then an ethics issue may arrive.

In conclusion we do not have many ethics issues to worry about with the current status of our project. We have uses C coding to create a completely custom multimedia streaming program that should not use any copyrighted libraries. We have not yet implemented the algorithm, but when this is implemented some ethics issues may arise. Also in the final paper and research submission more ethical issues may arise. If our project had other goals, such as selling a new multimedia streaming application that is faster and more efficient then current ones, then we would have a lot of ethical issues to deal with. Shown above are all the ethical issues we may have with our project.

9

Chapter VI: Future Work

By the end of this semester and after we have successfully accomplished the goals that we have set for this semester which were building UDP streaming multimedia program which has many assignments under that main part like using C programming language to design a sender (server) and receiver (client) programs in order to transmit the data through the network, splitting our data into small multiple packets, and using UDP as transmitter on our program. Then we tested our UDP streaming program and after we had tested our program we find out that it has some problems like the quality of the data and that our sender program sending more packets than we need. As result of that we will need to set other goals in addition to the goals that we have already set in the timeline and these goals will be the adding a feedback to the receiver side and encoding/decoding.

Our major future goal is implementing the fountain code to our UDP program and that will be in multiple steps. First step is writing the fountain code using the C program language, and this program will have the mixing matrix in order to encoding the source data and decoding the encoded data to get the original data after the transmission between the sender and receiver. The sender will have the fountain code, which will encode the data using the mixing matrix; on the other hand the receiver will have the fountain code, which will decode the encoded packets using the inverse of the mixing matrix, which will give us the original packets back. Second step will be using the feedback to inform the sender that the receiver side had received enough packets to decode them and get the original packets back and by that we will increase the efficiency by not sending more packets than needed.

After we have done with implementing the fountain code to our UDP program, now we could move to the next goal which will be testing and research in order to find out if our project has solved the problem and that will be through making some testing in our program to find out how well our program is working, then in the research part we could compare our results with other projects and researches about this topic to find out how efficient our program and if we have accomplished the goal of our project.

10

Chapter VII: Conclusion Streaming media has increased in demand, size, and speed as technology has advanced. The current protocol methods for streaming media efficiently are a significant bottleneck in the speed of streaming media. TCP and UDP methods have significant problems with efficiency and speed, and using UDP with fountain code algorithms is a good way to eliminate these problems. This semester we have finished a UDP streaming program, which is the base for testing the fountain code error correction. We have also created a traditional streaming program as well. Finally, we also took a lot of time to study and understand how current fountain code is used and implemented. Once we start testing fountain code we will be able to see if our hypothesis is confirmed or refuted. So far based on looking at past studies in fountain code, it is evident that fountain code can be more efficient. We will devote all of future research to fountain code testing.

11

References Kristen Purcell, The State of Online Video, Pew Internet & American Life Project, Jun 3, 2010, http://pewinternet.org/Reports/2010/State-of-Online-Video.aspx, Dec 7, 2010. MacKay, D.J.C.; , "Fountain codes," Communications, IEE Proceedings- , vol.152, no.6, pp. 1062- 1068, 9 Dec. 2005 doi: 10.1049/ip-com:20050237 Figure 1 - htp://www.tutorialsweb.com/networking/tcp-ip/udp-tcp.htm Figure 2 - http://www.freepatentsonline.com/6675340.html Figure 3 - http://www1.tlc.polito.it/sas-ipl/research_digital_fountains.php Figure 4 - MacKay, D.J.C.; , "Fountain codes,"

12

Appendix A – Abbreviations UDP – User Datagram Protocol TCP – Transmission Control Protocol LT code – Luby Transform code FEC – Forward Error Correction

13

Appendix B - Budget We have a budget of three hundred dollars. Fortunately we can do all of our programming on our personal computers. We needed some of the budget to print out materials for E-Days.

14

Appendix C – Code Sender: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> // argv[1]: the ip // argv[2]: the port // argv[3]: the file int main(int argc, char *argv[]) { /*int w; int numRecv = atoi(argv[1]); pid_t child_pid[numRecv]; for( w = 0; w<numRecv; w++) { if ((child_pid[i] = fork()) < 0) { perror("fork"); abort(); } else if (child_pid[i] == 0) { } } */ //--------------------------------------------------------------------------------------------- int recvPkg; int i = 0 ; int j = 0; int wait = 0; unsigned short pkgNo = 0; char * msg = (char *)malloc(2); //--------------------------------------------------------------------------------------------- // tcp variables and structure----------------------------------------------------------------- int sock_tcp; struct addrinfo hints_tcp, *result_tcp; memset(&hints_tcp, 0, sizeof hints_tcp); hints_tcp.ai_family = AF_UNSPEC; hints_tcp.ai_socktype = SOCK_STREAM; //udp variables and structure------------------------------------------------------------------ int sock_udp; struct addrinfo hints_udp, *result_udp; memset(&hints_udp, 0, sizeof hints_udp); hints_udp.ai_family = AF_UNSPEC; hints_udp.ai_socktype = SOCK_DGRAM; //tcp functions-------------------------------------------------------------------------------- getaddrinfo(argv[1], argv[2], &hints_tcp, &result_tcp); sock_tcp = socket(result_tcp->ai_family, result_tcp->ai_socktype, result_tcp->ai_protocol); connect(sock_tcp, result_tcp->ai_addr,result_tcp->ai_addrlen); printf("Done tcp\n"); //--------------------------------------------------------------------------------------------- i = recv(sock_tcp, msg, 10, 0); *(msg+i) = '\0'; printf("%s\n",msg); //--------------------------------------------------------------------------------------------- //udp functions-------------------------------------------------------------------------------- if (getaddrinfo(argv[1], argv[2], &hints_udp, &result_udp)!= 0) { printf("error getaddrinfo()\n");} sock_udp = socket(result_udp->ai_family, result_udp->ai_socktype, result_udp->ai_protocol); if (sock_udp == -1) { printf("error socket()\n");} printf("Done UDP\n"); //--------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- // open the file to be sent-------------------------------------------------------------------- FILE *rFile = fopen(argv[3], "rb"); fseek(rFile, 0 , SEEK_END); int fileSize = ftell(rFile); rewind(rFile); char *resend[(fileSize/1022)+1]; //============================================================================================- //store packeges for resending----------------------------------------------------------------- for (i = 0; i<((fileSize/1022)+1); i++) {

15

resend[i] = (char *)malloc(1024); } char * buffer = (char *)malloc(1024); i = 0; // sending file-------------------------------------------------------------------------------- while(1) { *buffer = (char )(pkgNo>>8); *(1+buffer) = (char)(pkgNo); i = fread((2+buffer), 1, 1022, rFile);// two bytes for the packet numebr memcpy(resend[pkgNo], buffer, i);//resend packet // send packet if (rand()%10!=1 || pkgNo >= ((fileSize/1022)+1)) { if (sendto(sock_udp, buffer, (i+2), 0, result_udp->ai_addr, result_udp->ai_addrlen) == -1) { printf("error sendto()\n"); return 0; } } else { // advance one packet to do miss pkgNo++; *buffer = (char)(pkgNo>>8); *(1+buffer) = (char)(pkgNo); i = fread((2+buffer), 1, 1022, rFile);// two bytes for the packet numebr memcpy(resend[pkgNo], buffer, i);//copy to a buffer for resendinf later if (sendto(sock_udp, buffer, (i+2), 0, result_udp->ai_addr, result_udp->ai_addrlen) == -1) { printf("error sendto()\n"); return 0; } } //the received pakacts //--------------------------------------// recv(sock_tcp, msg, 3, 0); // recvPkg= (unsigned short)*msg; // recvPkg<<=8; // recvPkg+= 255&(unsigned short)*(1+msg); // //--------------------------------------// if (recvPkg < pkgNo) { // resend recvPkg and pkgNo sendto(sock_udp, resend[recvPkg], (i+2), 0, result_udp->ai_addr, result_udp->ai_addrlen); while(wait !=5000) { wait++;} wait = 0; sendto(sock_udp, resend[pkgNo], (i+2), 0, result_udp->ai_addr, result_udp->ai_addrlen); } else { /*printf("recv %d\n", recvPkg);*/} if( i == 0) { printf("break loop\n"); break; } while(wait !=5000) { wait++;} wait = 0; pkgNo++; } return 0; }

16

Receiver: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> /** * getPkgNo: functiont to get the packet number from the packets. * pkgNo: is an unsigned short variable to store the packet numebr in. * buffer: has the packet that got received. */ void getPkgNo(unsigned short *pkgNo, char *buffer) { *pkgNo= (unsigned short)*buffer; *pkgNo<<=8; *pkgNo+= 255&(unsigned short)*(1+buffer); } /** * main:the main function, * argv[1]: port * argv[2]: outFile */ int main(int argc, char *argv[]) { int j = 0; // wait for write file to be enough for playing unsigned short pkgNo = 0; unsigned short PrepkgNo = 0; int i = 0; char *c = (char *)malloc(2); FILE *wFile = fopen(argv[2], "wb"); char *buffer = (char *)malloc(1024); //---------------------------------------------------------------------------- //tcp variables and structures struct sockaddr_storage their_addr_tcp; // connector's address information socklen_t sin_size; int sock_tcp, new_fd; struct addrinfo hints_tcp, *result_tcp; memset(&hints_tcp, 0, sizeof hints_tcp); hints_tcp.ai_family = AF_UNSPEC; hints_tcp.ai_socktype = SOCK_STREAM; hints_tcp.ai_flags = AI_PASSIVE; //udp variables and structure int sock_udp; struct addrinfo hints_udp, *result_udp; struct sockaddr_storage their_addr_udp; socklen_t addrlen; memset(&hints_udp, 0, sizeof hints_udp); hints_udp.ai_family = AF_UNSPEC; hints_udp.ai_socktype = SOCK_DGRAM; hints_udp.ai_flags = AI_PASSIVE; //tcp functions getaddrinfo(NULL, argv[1], &hints_tcp, &result_tcp); sock_tcp = socket(result_tcp->ai_family, result_tcp->ai_socktype, result_tcp->ai_protocol); bind(sock_tcp, result_tcp->ai_addr, result_tcp->ai_addrlen); printf("listening...\n"); listen(sock_tcp, 10); new_fd = accept(sock_tcp,(struct sockaddr *)&their_addr_tcp, &sin_size ); printf("tcp accept\n"); //udp functions getaddrinfo(NULL, argv[1], &hints_udp, &result_udp); sock_udp = socket(result_udp->ai_family, result_udp->ai_socktype, result_udp->ai_protocol); bind(sock_udp, result_udp->ai_addr, result_udp->ai_addrlen); printf("udp bind\n"); //------------------------------------ send(new_fd, "go", 2, 0); printf("waiting to receive\n"); // receiving file--------------------- while(1) { i = recvfrom(sock_udp, buffer, 1024, 0, (struct sockaddr *)&their_addr_udp, &addrlen); *c = *buffer; *(c+1) = *(1+buffer); getPkgNo(&pkgNo, buffer); // lost packets if((pkgNo - PrepkgNo) > 1) { *c = (char )((pkgNo-1)>>8); *(1+c) = (char)(pkgNo-1); send(new_fd, c, 2, 0); // Send the lost packet i = recvfrom(sock_udp, buffer, 1024, 0, (struct sockaddr *)&their_addr_udp, &addrlen); getPkgNo(&pkgNo, buffer);

17

printf("recv %d and ", pkgNo); if( (i-2) == 0) { printf("break\n");break;} fwrite((2+buffer),(i-2), 1,wFile); i = recvfrom(sock_udp, buffer, 1024, 0, (struct sockaddr *)&their_addr_udp, &addrlen); getPkgNo(&pkgNo, buffer); printf("%d\n", pkgNo); } else { printf("recv %d\n", pkgNo); send(new_fd, c, 2, 0);// send the packet received } if( (i-2) == 0)// to get out of the loop { printf("break\n"); return 0; } fwrite((2+buffer),(i-2), 1,wFile); /*if( j == 500) { char *temp[22]; sprintf(temp,"%s%s%s","mplayer ", argv[2], " &"); system(temp); }*/ PrepkgNo = pkgNo; pkgNo = 0; j++; } return 0; }