/* * Receives data and say who the sender is. (blocking function) */ bool CUdpSock::receivedFrom( uint8 *buffer, uint& len, CInetAddress& addr, bool throw_exception ) { // Receive incoming message sockaddr_in saddr; socklen_t saddrlen = sizeof(saddr); len = ::recvfrom( _Sock, (char*)buffer, len , 0, (sockaddr*)&saddr, &saddrlen ); // If an error occurs, the saddr is not valid // When the remote socket is closed, get sender's address to know who is quitting addr.setSockAddr( &saddr ); // Check for errors (after setting the address) if ( ((int)len) == SOCKET_ERROR ) { if ( throw_exception ) throw ESocket( "Cannot receive data" ); return false; } _BytesReceived += len; if ( _Logging ) { LNETL0_DEBUG( "LNETL0: Socket %d received %d bytes from %s", _Sock, len, addr.asString().c_str() ); } return true; }
/** Binds the socket to the specified port. Call bind() for an unreliable socket if the host acts as a server and waits for * messages. If the host acts as a client, call sendTo(), there is no need to bind the socket. */ void CUdpSock::bind( uint16 port ) { CInetAddress addr; // any IP address addr.setPort( port ); bind( addr ); setLocalAddress(); // will not set the address if the host is multihomed, use bind(CInetAddress) instead }
void CClient::updateStat () { // write each pong in a file string ha = Address.hostName(); if (ha.empty()) { ha = Address.ipAddress(); } string fn = StatPathName + ConnectionName + "_" + ha + "_" + getDate() + ".stat"; string line; line += "NbPing " + toString(NbPing) + " "; line += "NbPong " + toString(NbPong) + " "; if (NbPong == 0) line += "MeanPongTime <Undef> "; else line += "MeanPongTime " + toString(MeanPongTime/NbPong) + " "; line += "NbDuplicated " + toString(NbDuplicated) + " "; FILE *fp = fopen (fn.c_str(), "at"); if (fp == NULL) { nlwarning ("Can't open stat file name '%s'", fn.c_str()); } else { if (FirstWrite) { //nlassert (!Address.hostName().empty()) fprintf (fp, "HostAddress: %s\n", Address.asString().c_str()); FirstWrite = false; } fprintf (fp, "%s\n", line.c_str()); fclose (fp); } nlinfo (line.c_str()); CMessage msgout("INFO"); msgout.serial(line); CallbackServer->send (msgout, From); NbPing = NbPong = MeanPongTime = NbDuplicated = 0; }
void CDummyTcpSock::connect( const CInetAddress& addr ) { _RemoteAddr = addr; _Sock = 100; _BytesReceived = 0; _BytesSent = 0; //CSynchronized<bool>::CAccessor sync( &_SyncConnected ); //sync.value() = true; _Connected = true; LNETL0_DEBUG( "LNETL0: Socket connected to %s", addr.asString().c_str() ); }
/* * Sends a message */ void CUdpSock::sendTo( const uint8 *buffer, uint len, const CInetAddress& addr ) { // Send if ( ::sendto( _Sock, (const char*)buffer, len, 0, (sockaddr*)(addr.sockAddr()), sizeof(sockaddr) ) != (sint32)len ) { throw ESocket( "Unable to send datagram" ); } _BytesSent += len; if ( _Logging ) { LNETL0_DEBUG( "LNETL0: Socket %d sent %d bytes to %s", _Sock, len, addr.asString().c_str() ); } // If socket is unbound, retrieve local address if ( ! _Bound ) { setLocalAddress(); _Bound = true; } #ifdef NL_OS_WINDOWS // temporary by ace to know size of SO_MAX_MSG_SIZE static bool first = true; if (first) { uint MMS, SB; int size = sizeof (MMS); getsockopt (_Sock, SOL_SOCKET, SO_SNDBUF, (char *)&SB, &size); getsockopt (_Sock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&MMS, &size); LNETL0_INFO ("LNETL0: The udp SO_MAX_MSG_SIZE=%u, SO_SNDBUF=%u", MMS, SB); first = false; } #endif }
void CClient::updateFullStat () { uint32 NbLost = 0, NbDup = 0, NbPong = 0; /* if (Address.hostName().empty()) { // don't log because we receive no pong at all return; }*/ for (uint i = 0; i < LastPongReceived; i++) { if (PongReceived[i].first == 0) NbLost++; else { NbPong++; NbDup += PongReceived[i].first - 1; } } { // write each pong in a file string ha = Address.hostName(); if (ha.empty()) { ha = Address.ipAddress(); } string fn = StatPathName + ConnectionName + "_" + ha + "_" + getDate() + ".stat"; string line = "Full Summary: "; line += "NbPing " + toString(LastPongReceived) + " "; line += "NbPong " + toString(NbPong) + " "; line += "NbLost " + toString(NbLost) + " "; if (LastPongReceived>0) line += "(" + toString((float)NbLost/LastPongReceived*100.0f) + "pc) "; line += "NbDuplicated " + toString(NbDup) + " "; if (LastPongReceived>0) line += "(" + toString((float)NbDup/LastPongReceived*100.0f) + "pc) "; if (FullNbPong == 0) line += "MeanPongTime <Undef> "; else line += "MeanPongTime " + toString(FullMeanPongTime/FullNbPong) + " "; FILE *fp = fopen (fn.c_str(), "at"); if (fp == NULL) { nlwarning ("Can't open stat file name '%s'", fn.c_str()); } else { fprintf (fp, "%s\n", line.c_str()); fclose (fp); // send the full sumary to the client CMessage msgout("INFO"); msgout.serial(line); CallbackServer->send (msgout, From); } nlinfo (line.c_str()); } { // write each ping in a file string ha = Address.hostName(); if (ha.empty()) { ha = Address.ipAddress(); } string fn = StatPathName + ConnectionName + "_" + ha + "_" + getDate() + ".ping"; FILE *fp = fopen (fn.c_str(), "rt"); if (fp == NULL) { // new file, add the header FILE *fp = fopen (fn.c_str(), "wt"); if (fp != NULL) { fprintf (fp, "#%s\t%s\n", "NbPongRcv", "Delta"); fclose (fp); } } else { fclose (fp); } fp = fopen (fn.c_str(), "at"); if (fp == NULL) { nlwarning ("Can't open ping file name '%s'", fn.c_str()); } else { // add a fake value to know that it s a different session fprintf (fp, "-1\t0\n"); for (uint i = 0; i < LastPongReceived; i++) { fprintf (fp, "%d\t%d\n", PongReceived[i].first, PongReceived[i].second); } fclose (fp); } } // clear all structures PongReceived.clear (); PongReceived.resize (1001); BlockNumber++; NextPingNumber = LastPongReceived = 0; FullMeanPongTime = FullNbPong = 0; // NbPing = NbPong = MeanPongTime = NbDuplicated = 0; }
void CClient::updatePong (sint64 pingTime, sint64 pongTime, uint32 pongNumber, uint32 blockNumber) { // it means that it s a too old packet, discard it if (blockNumber != BlockNumber) return; // add the pong in the array to detect lost, duplication if (pongNumber >= PongReceived.size()) { // if the array is too big, we flush actual data and restart all updateFullStat (); return; } PongReceived[pongNumber].first++; if (PongReceived[pongNumber].first > 1) { NbDuplicated++; } else { // increase only for new pong NbPong++; MeanPongTime += (uint32)(pongTime-pingTime); FullNbPong++; FullMeanPongTime += (uint32)(pongTime-pingTime); PongReceived[pongNumber].second = (uint16)(pongTime - pingTime); } if (pongNumber > LastPongReceived) LastPongReceived = pongNumber; // write each pong in a file string ha = Address.hostName(); if (ha.empty()) { ha = Address.ipAddress(); } string fn = StatPathName + ConnectionName + "_" + ha + "_" + getDate() + ".pong"; FILE *fp = fopen (fn.c_str(), "rt"); if (fp == NULL) { // new file, add the header FILE *fp = fopen (fn.c_str(), "wt"); if (fp != NULL) { fprintf (fp, "#%s\t%s\t%s\t%s\n", "PingTime", "PongTime", "Delta", "PingNumber"); fclose (fp); } } else { fclose (fp); } fp = fopen (fn.c_str(), "at"); if (fp == NULL) { nlwarning ("Can't open pong file name '%s'", fn.c_str()); } else { fprintf (fp, "%"NL_I64"d\t%"NL_I64"d\t%"NL_I64"d\t%d\n", pongTime, pingTime, (pongTime-pingTime), pongNumber); fclose (fp); } }