00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "balser.h"
00025 #include <list>
00026
00027 #define DEFAULT_PORT 2051
00028 #define DEFAULT_IP "127.0.0.1"
00029
00030 using namespace std;
00031 using namespace Cabal;
00032
00033 class pkt_account
00034 {
00035 public:
00036 pkt_account( MSECS t, int l )
00037 {
00038 arr_time = t;
00039 length = l;
00040 }
00041
00042 MSECS arr_time;
00043 int length;
00044 };
00045
00046 list< pkt_account> accountList;
00047
00048 void calcBandwidth( double &immediate, double &mean )
00049 {
00050 double totalSec = 0.0;
00051 double totalTime = 0.0;
00052 double totalData = 0.0;
00053
00054 list< pkt_account>::iterator iter = accountList.begin();
00055 MSECS now = iter->arr_time;
00056
00057 int size = 0;
00058 while( iter != accountList.end() )
00059 {
00060 if ( iter->arr_time > now - 1000 ) {
00061 totalSec += iter->length;
00062 }
00063 totalData += iter->length;
00064
00065 totalTime = iter->arr_time;
00066 iter++;
00067 size++;
00068 }
00069
00070 immediate = totalSec;
00071 if ( (now - totalTime) > 0 )
00072 mean = totalData / ( now - totalTime ) * (size-1)/(size) *1000.0;
00073 else
00074 mean = 0;
00075 }
00076
00079 void communicate( UDPSocket &skt, unsigned long userId, Address &remote, PACKET *pkt )
00080 {
00081 MSECS lastTime;
00082
00083 do {
00084 lastTime = Net::timeOfDay();
00085
00086 accountList.push_front( pkt_account( lastTime, sizeof( PACKET ) ) );
00087
00088 double instant, mean;
00089 calcBandwidth( instant, mean );
00090 cout << "\r" << instant << "b/sec " << mean << "b/sec ";
00091
00092 unsigned char check = static_cast<unsigned char>( pkt->id );
00093 bool correct = true;
00094 for( int pos = 0; pos < sizeof( pkt->data ); pos ++ )
00095 {
00096 if ( static_cast<unsigned char>(pkt->data[pos]) != check ) {
00097 correct = false;
00098 break;
00099 }
00100 }
00101
00102
00103 CLI_REQ *req = reinterpret_cast<CLI_REQ *>(pkt->data);
00104 if ( ! correct )
00105 {
00106 req->type = REQ_TYPE_RESEND;
00107 req->value = pkt->id;
00108
00109 cout <<"!" <<flush;
00110 }
00111 else {
00112 req->type = REQ_TYPE_ACK;
00113 req->value = pkt->id;
00114 }
00115
00116 for ( int i = 0; i < accountList.size(); i ++ )
00117
00118 cout <<"#";
00119
00120 cout << flush;
00121
00122
00123 skt.timeout( 250 );
00124 int retval = 0;
00125
00126
00127 retval = skt.sendTo( pkt, CLIENT_REP_SIZE, remote );
00128 if ( retval <= 0 ) {
00129 cout << "Error on socket " << skt.osError() << ": " <<
00130 Net::errorDescription( skt.osError() ) << endl;
00131 return;
00132 }
00133
00134 skt.timeout( 2500 );
00135 while ( lastTime + 2500 > Net::timeOfDay() )
00136 {
00137 retval = skt.recv( pkt, 1500 );
00138 if ( retval > 0 ) {
00139 if ( skt.remote() != remote ) {
00140 cout << "Received unexpected traffic from " << remote.ip() << ":" << remote.port() << endl;
00141 }
00142 else if ( retval != sizeof( PACKET ) || pkt->userId != userId ) {
00143 cout << "Received spurious " << retval << " bytes from " << remote.ip() << ":" << remote.port() << endl;
00144 }
00145 else
00146 break;
00147 }
00148 else if (retval < 0 )
00149 {
00150 cout << "Error on socket " << skt.osError() << ": " <<
00151 Net::errorDescription( skt.osError() ) << endl;
00152 return;
00153 }
00154 }
00155
00156 if ( retval == 0 ) {
00157 cout << "Server transmission timed out " << endl;
00158 return;
00159 }
00160 } while( pkt->id != END_CONNECT );
00161
00162 }
00163
00164
00165
00166
00167 int main ( int argc, char *argv[] )
00168 {
00169 int n_port;
00170 char *c_ip;
00171
00172 if ( argc == 3 ) {
00173 c_ip = argv[1];
00174 n_port = atoi( argv[2] );
00175 }
00176 else if ( argc == 2 ) {
00177 c_ip = DEFAULT_IP;
00178 n_port = atoi( argv[1] );
00179 }
00180 else {
00181 c_ip = DEFAULT_IP;
00182 n_port = DEFAULT_PORT;
00183 }
00184
00185
00186 try {
00187 bool connected;
00188 char buffer[1500];
00189 PACKET *pkt = reinterpret_cast< PACKET *>( buffer );
00190
00191 Net::init();
00192 UDPSocket skt;
00193 Address remote( c_ip, n_port ), incoming;
00194
00195 skt.timeout( 2500 );
00196 cout << "Sending UDP connection request." << endl;
00197 pkt->userId = START_CONNECT;
00198
00199 connected = false;
00200
00201 for ( int tries = 0; tries < 3; tries ++ )
00202 {
00203 if ( skt.sendTo( pkt, CLIENT_REP_SIZE, remote ) != CLIENT_REP_SIZE )
00204 {
00205 cout << "Error on first send " << skt.osError() << ": " <<
00206 Net::errorDescription( skt.osError() ) << endl;
00207 break;
00208 }
00209
00210 int recvd = skt.recvFrom( pkt, 1500, incoming );
00211 if ( recvd < 0 ) {
00212 cout << "Error on first recv " << skt.osError() << ": " <<
00213 Net::errorDescription( skt.osError() ) << endl;
00214 break;
00215 }
00216 else if ( recvd == 0 ) {
00217 cout << "Timedout wihile waiting. Resending." << endl;
00218 continue;
00219 }
00220 else if ( recvd < sizeof( PACKET ) )
00221 {
00222 cout << "Received spurious data." <<endl;
00223 }
00224 else if ( incoming != remote ) {
00225 cout << "Received different traffic source: " << incoming.ip() << endl;
00226 }
00227 else {
00228 cout << "Begin of transmissions." << endl;
00229 connected = true;
00230 break;
00231 }
00232
00233 }
00234
00235 if ( connected )
00236 {
00237 communicate( skt, pkt->userId, remote, pkt );
00238 }
00239
00240 skt.close();
00241 cout << endl << "Done" << endl;
00242 Net::exit();
00243 }
00244 catch (Error e ) {
00245 cout << e <<"\n";
00246 }
00247
00248 return 0;
00249 }
00250
00251