Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Router Head file
- #ifndef ROUTER_H
- #define ROUTER_H
- #pragma comment( linker, "/defaultlib:ws2_32.lib" )
- #include <winsock2.h>
- #include <fstream>
- #include <iostream>
- #include <time.h>
- #include <list>
- #include <stdio.h>
- using namespace std ;
- #define MAXBUFSIZE 2048 //maximum packet size
- #define MAXHOSTNAMELEN 256 //maximum length of host name
- #define ROUTER_PORT1 7000 //router port number 1
- #define ROUTER_PORT2 7001 //router port number 2
- #define PEER_PORT1 5000 //port number of peer host 1
- #define PEER_PORT2 5001 //port number of peer host 2
- #define TIMEOUT_USEC 300000 //time-out value
- #define TRACE 1
- struct EVENT_LIST
- {
- bool empty;
- DWORD count; //count is the packet number
- short destination; //destination of this packet
- int len; //length of this packet
- char Buffer[MAXBUFSIZE]; //buffer for packet
- };
- class Router
- {
- public:
- char localhost[MAXHOSTNAMELEN]; //local host name
- //Constructor
- Router(char *fn="log.txt");
- //Destructor
- ~Router();
- void Run();
- private:
- ofstream fout; //log file
- float damage_rate, delay_rate; //damage rate: dropped and delayed
- SOCKET Sock1, Sock2; //sockets used for communcation with peer host 1 and 2
- EVENT_LIST FileBuf; //buffer for delayed packets
- protected:
- SOCKADDR_IN sa_in_peer1; // address structure for peer host 1 address
- SOCKADDR_IN sa_in_peer2; // address structure for peer host 2 address
- bool IsDamage() const;
- bool IsDelayed() const;
- void SendProc();
- };
- #endif
- //Router.cpp
- #include "Router.h"
- //////////////////////////////////////////////////////////
- //
- // Router Constructor
- // arguements:
- // fn: A string of log file name
- //
- //////////////////////////////////////////////////////////
- Router::Router(char *fn) //Constructor
- {
- WSADATA wsadata;
- HOSTENT* hp;
- char peer_name1[MAXHOSTNAMELEN], peer_name2[MAXHOSTNAMELEN];
- SOCKADDR_IN sa_in;
- FileBuf.empty=true;
- try
- {
- if (WSAStartup(0x0202,&wsadata)!=0)
- throw "Error in starting WSAStartup()\n";
- }
- //Display any needed error response.
- catch (char *str) { cerr<<str<<":"<<dec<<WSAGetLastError()<<endl; return;}
- //Get Host name
- gethostname(localhost,MAXHOSTNAMELEN);
- cout<<"Router starting on host:"<<localhost<<endl<<flush;
- //Open the log file
- fout.open(fn);
- try
- {
- //Create the Udp Sock1
- if((Sock1 = socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET)
- throw "Create UDP Socket1 failed\n";
- //Fill-in UDP Port and Address info.
- sa_in.sin_family = AF_INET;
- sa_in.sin_port = htons(ROUTER_PORT1);
- sa_in.sin_addr.s_addr = htonl(INADDR_ANY);
- //Bind the UDP port1
- if (bind(Sock1,(LPSOCKADDR)&sa_in,sizeof(sa_in)) == SOCKET_ERROR)
- throw "can't bind the socket1";
- //Create the Udp Sock2
- if((Sock2 = socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET)
- throw "Create UDP Socket2 failed\n";
- //Fill-in UDP Port and Address info.
- sa_in.sin_family = AF_INET;
- sa_in.sin_port = htons(ROUTER_PORT2);
- sa_in.sin_addr.s_addr = htonl(INADDR_ANY);
- //Bind the UDP port2
- if (bind(Sock2,(LPSOCKADDR)&sa_in,sizeof(sa_in)) == SOCKET_ERROR)
- throw "can't bind the socket2";
- cout<<"\nPlease enter the first peer host name:"<<flush; //enter the dropping rate.
- cin>>peer_name1;
- cout<<"\nPlease enter the second peer host name:"<<flush; //enter the dropping rate.
- cin>>peer_name2;
- cout<<"\nPlease enter the drop rate:"<<flush; //enter the dropping rate.
- cin>>damage_rate;
- cout<<"\nPlease enter the delay rate:"<<flush; //enter the dropping rate.
- cin>>delay_rate;
- //creat peer host1
- if((hp=gethostbyname(peer_name1)) == NULL)
- throw "get server name failed\n";
- memset(&sa_in_peer1,0,sizeof(sa_in_peer1));
- memcpy(&sa_in_peer1.sin_addr,hp->h_addr,hp->h_length);
- sa_in_peer1.sin_family = hp->h_addrtype;
- sa_in_peer1.sin_port = htons(PEER_PORT1);
- //creat peer host2
- if((hp=gethostbyname(peer_name2)) == NULL)
- throw "get client name failed\n";
- memset(&sa_in_peer2,0,sizeof(sa_in_peer2));
- memcpy(&sa_in_peer2.sin_addr,hp->h_addr,hp->h_length);
- sa_in_peer2.sin_family = hp->h_addrtype;
- sa_in_peer2.sin_port = htons(PEER_PORT2);
- if (TRACE)
- {
- fout<<"Peer host 1: "<<peer_name1<<endl;
- fout<<"Peer host 2: "<<peer_name2<<endl;
- fout<<"Damage Rate: "<<damage_rate<<endl;
- }
- }
- catch (char *str) {cerr<<str<<":"<<dec<<WSAGetLastError()<<endl; exit(1);}
- srand( (unsigned)time( NULL ) );
- }
- //////////////////////////////////////////////////////////
- //
- // Router::IsDamage
- // The function that generates random damages according to damage rate.
- //
- //////////////////////////////////////////////////////////
- bool Router::IsDamage() const
- {
- return ( (((float)rand())/RAND_MAX) < ((float)damage_rate/100));
- }
- //////////////////////////////////////////////////////////
- //
- // Router::IsDelayed
- // The function that generates random delayed according to delay rate.
- //
- //////////////////////////////////////////////////////////
- bool Router::IsDelayed() const
- {
- return ( (((float)rand())/RAND_MAX) < ((float)delay_rate/100));
- }
- //////////////////////////////////////////////////////////
- //
- // Router::Run
- // The function receives packets from peer hosts and forwards to destinations.
- // It also drops packets and stores delayed packets for future sending.
- // It calls SendProc to send delayed packets.
- //
- //////////////////////////////////////////////////////////
- void Router::Run()
- {
- fd_set readfds;
- struct timeval *tp=new timeval;
- SOCKADDR from;
- int RetVal, fromlen, recvlen, wait_count;
- EVENT_LIST temp;
- DWORD CurrentTime, count1, count2;
- count1=0;
- count2=0;
- wait_count=0;
- tp->tv_sec=0;
- tp->tv_usec=TIMEOUT_USEC;
- while (1)
- {
- try
- {
- FD_ZERO(&readfds);
- FD_SET(Sock1,&readfds);
- FD_SET(Sock2,&readfds);
- fromlen=sizeof(from);
- if((RetVal=select(1,&readfds,NULL,NULL,tp))==SOCKET_ERROR) //check for incoming packets.
- throw "Timer error!";
- else if(RetVal>0) //There are incoming packets.
- {
- if(!FileBuf.empty) wait_count++;
- if(FD_ISSET(Sock1, &readfds)) //incoming packet from peer host 1
- {
- if((recvlen=recvfrom(Sock1, temp.Buffer, sizeof(temp.Buffer), 0, &from, &fromlen))==SOCKET_ERROR)
- throw " Get buffer error!";
- if (TRACE)
- {
- fout<<"Router: Receive packet "<<count1<<" from peer host 1"<<endl;
- cout<<"Router: Receive packet "<<count1<<" from peer host 1"<<endl;
- }
- temp.count=count1;
- count1++;
- temp.destination=2;
- }
- else if(FD_ISSET(Sock2, &readfds)) //incoming packet from peer host 2
- {
- if((recvlen=recvfrom(Sock2, temp.Buffer, sizeof(temp.Buffer), 0, &from, &fromlen))==SOCKET_ERROR)
- throw " Get buffer error!";
- if (TRACE)
- {
- fout<<"Router: Receive packet "<<count2<<" from peer host 2"<<endl;
- cout<<"Router: Receive packet "<<count2<<" from peer host 2"<<endl;
- }
- temp.count=count2;
- count2++;
- temp.destination=1;
- }
- else continue;
- temp.len=recvlen;
- CurrentTime=GetTickCount();
- if(FileBuf.empty&&IsDelayed()) //if the packet is delayed.
- {
- FileBuf=temp;
- FileBuf.empty=false;
- if (TRACE)
- {
- fout<<"Router: Packet "<<temp.count<<" received from peer host "<<(temp.destination==1?2:1)<<" has been delayed!"<<endl;
- cout<<"Router: Packet "<<temp.count<<" received from peer host "<<(temp.destination==1?2:1)<<" has been delayed!"<<endl;
- }
- }
- else if(IsDamage()) //if the packet is dropped: dropping packet by no forwarding the packet.
- {
- if (TRACE)
- {
- fout<<"Router: Packet "<<temp.count<<" received from peer host "<<(temp.destination==1?2:1)<<" has been dropped by router!"<<endl;
- cout<<"Router: Packet "<<temp.count<<" received from peer host "<<(temp.destination==1?2:1)<<" has been dropped by router!"<<endl;
- }
- }
- else //otherwise, packet is forwarded to destination
- {
- if(temp.destination==1) //forward packets received from 2 to 1.
- {
- if(sendto(Sock1, temp.Buffer, temp.len,0,(SOCKADDR*)&sa_in_peer1,sizeof(sa_in_peer1))==SOCKET_ERROR)
- throw "Send packet error!";
- if (TRACE)
- {
- fout<<"Router: Send packet "<<temp.count<<" received from peer host "<<(temp.destination==1?2:1) <<" to host "<<temp.destination<<endl;
- cout<<"Router: Send packet "<<temp.count<<" received from peer host "<<(temp.destination==1?2:1) <<" to host "<<temp.destination<<endl;
- }
- if(!FileBuf.empty&&FileBuf.destination==1)
- {
- wait_count=0;
- SendProc();
- }
- }
- else
- { //forward packets received from 1 to 2.
- if(sendto(Sock2, temp.Buffer, temp.len,0,(SOCKADDR*)&sa_in_peer2,sizeof(sa_in_peer2))==SOCKET_ERROR)
- throw "Send packet error1";
- if (TRACE)
- {
- fout<<"Router: Send packet "<<temp.count<<" received from peer host "<<(temp.destination==1?2:1) <<" to host "<<temp.destination<<endl;
- cout<<"Router: Send packet "<<temp.count<<" received from peer host "<<(temp.destination==1?2:1) <<" to host "<<temp.destination<<endl;
- }
- if(!FileBuf.empty&&FileBuf.destination==2)
- {
- wait_count=0;
- SendProc();
- }
- }
- }
- }
- else //If there is no incoming packet and there is a delayed packets storing in buffer for 3 cycle times (about 0.9 second), call SendProc to send delayed packet.
- {
- if(!FileBuf.empty)
- {
- wait_count++;
- if(wait_count>=3)
- {
- SendProc();
- wait_count=0;
- }
- }
- }
- } //end of try
- catch(char *str) {cerr<<str<<":"<<dec<<WSAGetLastError()<<endl;}
- }//end of while
- }
- //////////////////////////////////////////////////////////
- //
- // Router::SendProc
- // Send delayed packets to the destinations.
- //
- //////////////////////////////////////////////////////////
- void Router::SendProc()
- {
- try
- {
- if(FileBuf.destination==1)
- {
- if(sendto(Sock1, FileBuf.Buffer, FileBuf.len,0,(SOCKADDR*)&sa_in_peer1,sizeof(sa_in_peer1))==SOCKET_ERROR)
- throw "Send packet error!";
- }
- else
- {
- if(sendto(Sock2, FileBuf.Buffer, FileBuf.len,0,(SOCKADDR*)&sa_in_peer2,sizeof(sa_in_peer2))==SOCKET_ERROR)
- throw "Send packet error!";
- }
- if (TRACE)
- {
- fout<<"Router: Send delayed packet "<<FileBuf.count<<" received from peer host "<<(FileBuf.destination==1?2:1)<<" to host "<<FileBuf.destination<<endl;
- cout<<"Router: Send delayed packet "<<FileBuf.count<<" received from peer host "<<(FileBuf.destination==1?2:1)<<" to host "<<FileBuf.destination<<endl;
- }
- }
- catch(char *str){cerr<<str<<":"<<dec<<WSAGetLastError()<<endl;}
- FileBuf.empty=true;
- }
- //////////////////////////////////////////////////////////
- //
- // Router Destructor
- // arguements:
- // fn: A string of log file name
- //
- //////////////////////////////////////////////////////////
- Router :: ~Router()
- {
- closesocket(Sock1);
- closesocket(Sock2);
- /* When done, uninstall winsock.dll (WSACleanup()) and exit */
- WSACleanup();
- //close log file
- fout.close();
- }
- //////////////////////////////////////////////////////////
- //
- // Main function
- //
- //////////////////////////////////////////////////////////
- void main()
- {
- Router router;
- router.Run();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement