⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listener.cpp

📁 在Linux/Unix环境下发包测试性能的工具
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        struct ip_mreq mreq;        memcpy( &mreq.imr_multiaddr, SockAddr_get_in_addr( &mSettings->local ),                 sizeof(mreq.imr_multiaddr));        mreq.imr_interface.s_addr = htonl( INADDR_ANY );        int rc = setsockopt( mSettings->mSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,                             (char*) &mreq, sizeof(mreq));        WARN_errno( rc == SOCKET_ERROR, "multicast join" );    }#ifdef HAVE_IPV6_MULTICAST      else {        struct ipv6_mreq mreq;        memcpy( &mreq.ipv6mr_multiaddr, SockAddr_get_in6_addr( &mSettings->local ),                 sizeof(mreq.ipv6mr_multiaddr));        mreq.ipv6mr_interface = 0;        int rc = setsockopt( mSettings->mSock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,                             (char*) &mreq, sizeof(mreq));        WARN_errno( rc == SOCKET_ERROR, "multicast join" );    }#endif#endif}// end McastJoin/* ------------------------------------------------------------------- * Sets the Multicast TTL for outgoing packets. * ------------------------------------------------------------------- */void Listener::McastSetTTL( int val ) {#ifdef HAVE_MULTICAST    if ( !SockAddr_isIPv6( &mSettings->local ) ) {        int rc = setsockopt( mSettings->mSock, IPPROTO_IP, IP_MULTICAST_TTL,                             (char*) &val, sizeof(val));        WARN_errno( rc == SOCKET_ERROR, "multicast ttl" );    }#ifdef HAVE_IPV6_MULTICAST      else {        int rc = setsockopt( mSettings->mSock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,                             (char*) &val, sizeof(val));        WARN_errno( rc == SOCKET_ERROR, "multicast ttl" );    }#endif#endif}// end McastSetTTL/* ------------------------------------------------------------------- * After Listen() has setup mSock, this will block * until a new connection arrives. * ------------------------------------------------------------------- */void Listener::Accept( thread_Settings *server ) {    server->size_peer = sizeof(iperf_sockaddr);     if ( isUDP( server ) ) {        /* -------------------------------------------------------------------          * Do the equivalent of an accept() call for UDP sockets. This waits          * on a listening UDP socket until we get a datagram.          * ------------------------------------------------------------------- */        int rc;        Iperf_ListEntry *exist;        int32_t datagramID;        server->mSock = INVALID_SOCKET;        while ( server->mSock == INVALID_SOCKET ) {            rc = recvfrom( mSettings->mSock, mBuf, mSettings->mBufLen, 0,                            (struct sockaddr*) &server->peer, &server->size_peer );            FAIL_errno( rc == SOCKET_ERROR, "recvfrom", mSettings );            Mutex_Lock( &clients_mutex );                // Handle connection for UDP sockets.            exist = Iperf_present( &server->peer, clients);            datagramID = ntohl( ((UDP_datagram*) mBuf)->id );             if ( exist == NULL && datagramID >= 0 ) {                server->mSock = mSettings->mSock;                int rc = connect( server->mSock, (struct sockaddr*) &server->peer,                                  server->size_peer );                FAIL_errno( rc == SOCKET_ERROR, "connect UDP", mSettings );            } else {                server->mSock = INVALID_SOCKET;            }            Mutex_Unlock( &clients_mutex );        }    } else {        // Handles interupted accepts. Returns the newly connected socket.        server->mSock = INVALID_SOCKET;            while ( server->mSock == INVALID_SOCKET ) {            // accept a connection            server->mSock = accept( mSettings->mSock,                                     (sockaddr*) &server->peer, &server->size_peer );            if ( server->mSock == INVALID_SOCKET &&  errno == EINTR ) {                continue;            }        }    }    server->size_local = sizeof(iperf_sockaddr);     getsockname( server->mSock, (sockaddr*) &server->local,                  &server->size_local );} // end Acceptvoid Listener::UDPSingleServer( ) {        bool client = false, UDP = isUDP( mSettings ), mCount = (mSettings->mThreads != 0);    thread_Settings *tempSettings = NULL;    Iperf_ListEntry *exist, *listtemp;    int rc;    int32_t datagramID;    client_hdr* hdr = ( UDP ? (client_hdr*) (((UDP_datagram*)mBuf) + 1) :                               (client_hdr*) mBuf);    ReportStruct *reportstruct = new ReportStruct;        if ( mSettings->mHost != NULL ) {        client = true;        SockAddr_remoteAddr( mSettings );    }    Settings_Copy( mSettings, &server );    server->mThreadMode = kMode_Server;    // Accept each packet,     // If there is no existing client, then start      // a new report to service the new client     // The listener runs in a single thread     Mutex_Lock( &clients_mutex );    do {        // Get next packet        while ( sInterupted == 0) {            server->size_peer = sizeof( iperf_sockaddr );            rc = recvfrom( mSettings->mSock, mBuf, mSettings->mBufLen, 0,                            (struct sockaddr*) &server->peer, &server->size_peer );            WARN_errno( rc == SOCKET_ERROR, "recvfrom" );            if ( rc == SOCKET_ERROR ) {                return;            }                            // Handle connection for UDP sockets.            exist = Iperf_present( &server->peer, clients);            datagramID = ntohl( ((UDP_datagram*) mBuf)->id );             if ( datagramID >= 0 ) {                if ( exist != NULL ) {                    // read the datagram ID and sentTime out of the buffer                     reportstruct->packetID = datagramID;                     reportstruct->sentTime.tv_sec = ntohl( ((UDP_datagram*) mBuf)->tv_sec  );                    reportstruct->sentTime.tv_usec = ntohl( ((UDP_datagram*) mBuf)->tv_usec );                             reportstruct->packetLen = rc;                    gettimeofday( &(reportstruct->packetTime), NULL );                            ReportPacket( exist->server->reporthdr, reportstruct );                } else {                    Mutex_Lock( &groupCond );                    groupID--;                    server->mSock = -groupID;                    Mutex_Unlock( &groupCond );                    server->size_local = sizeof(iperf_sockaddr);                     getsockname( mSettings->mSock, (sockaddr*) &server->local,                                  &server->size_local );                    break;                }            } else {                if ( exist != NULL ) {                    // read the datagram ID and sentTime out of the buffer                     reportstruct->packetID = -datagramID;                     reportstruct->sentTime.tv_sec = ntohl( ((UDP_datagram*) mBuf)->tv_sec  );                    reportstruct->sentTime.tv_usec = ntohl( ((UDP_datagram*) mBuf)->tv_usec );                             reportstruct->packetLen = rc;                    gettimeofday( &(reportstruct->packetTime), NULL );                            ReportPacket( exist->server->reporthdr, reportstruct );                    // stop timing                     gettimeofday( &(reportstruct->packetTime), NULL );                    CloseReport( exist->server->reporthdr, reportstruct );                            if ( rc > (int) ( sizeof( UDP_datagram )                                                      + sizeof( server_hdr ) ) ) {                        UDP_datagram *UDP_Hdr;                        server_hdr *hdr;                                UDP_Hdr = (UDP_datagram*) mBuf;                        Transfer_Info *stats = GetReport( exist->server->reporthdr );                        hdr = (server_hdr*) (UDP_Hdr+1);                                hdr->flags        = htonl( HEADER_VERSION1 );                        hdr->total_len1   = htonl( (long) (stats->TotalLen >> 32) );                        hdr->total_len2   = htonl( (long) (stats->TotalLen & 0xFFFFFFFF) );                        hdr->stop_sec     = htonl( (long) stats->endTime );                        hdr->stop_usec    = htonl( (long)((stats->endTime - (long)stats->endTime)                                                          * rMillion));                        hdr->error_cnt    = htonl( stats->cntError );                        hdr->outorder_cnt = htonl( stats->cntOutofOrder );                        hdr->datagrams    = htonl( stats->cntDatagrams );                        hdr->jitter1      = htonl( (long) stats->jitter );                        hdr->jitter2      = htonl( (long) ((stats->jitter - (long)stats->jitter)                                                            * rMillion) );                            }                    EndReport( exist->server->reporthdr );                    exist->server->reporthdr = NULL;                    Iperf_delete( &(exist->server->peer), &clients );                } else if ( rc > (int) ( sizeof( UDP_datagram )                                                  + sizeof( server_hdr ) ) ) {                    UDP_datagram *UDP_Hdr;                    server_hdr *hdr;                            UDP_Hdr = (UDP_datagram*) mBuf;                    hdr = (server_hdr*) (UDP_Hdr+1);                    hdr->flags = htonl( 0 );                }                sendto( mSettings->mSock, mBuf, mSettings->mBufLen, 0,                        (struct sockaddr*) &server->peer, server->size_peer);            }        }        if ( server->mSock == INVALID_SOCKET ) {            break;        }        if ( sInterupted != 0 ) {            close( server->mSock );            break;        }        // Reset Single Client Stuff        if ( isSingleClient( mSettings ) && clients == NULL ) {            mSettings->peer = server->peer;            mClients--;            client = true;            // Once all the server threads exit then quit            // Must keep going in case this client sends            // more streams            if ( mClients == 0 ) {                thread_release_nonterm( 0 );                mClients = 1;            }        }        // Verify that it is allowed        if ( client ) {            if ( !SockAddr_Hostare_Equal( (sockaddr*) &mSettings->peer,                                           (sockaddr*) &server->peer ) ) {                // Not allowed try again                connect( mSettings->mSock,                          (sockaddr*) &server->peer,                          server->size_peer );                close( mSettings->mSock );                mSettings->mSock = -1;                 Listen( );                continue;            }        }        // Create an entry for the connection list        listtemp = new Iperf_ListEntry;        memcpy(listtemp, &server->peer, sizeof(iperf_sockaddr));        listtemp->server = server;        listtemp->next = NULL;        // See if we need to do summing        exist = Iperf_hostpresent( &server->peer, clients);         if ( exist != NULL ) {            // Copy group ID            listtemp->holder = exist->holder;            server->multihdr = exist->holder;        } else {            server->mThreads = 0;            Mutex_Lock( &groupCond );            groupID--;            listtemp->holder = InitMulti( server, groupID );            server->multihdr = listtemp->holder;            Mutex_Unlock( &groupCond );        }        // Store entry in connection list        Iperf_pushback( listtemp, &clients );         tempSettings = NULL;        if ( !isCompat( mSettings ) && !isMulticast( mSettings ) ) {            Settings_GenerateClientSettings( server, &tempSettings,                                               hdr );        }        if ( tempSettings != NULL ) {            client_init( tempSettings );            if ( tempSettings->mMode == kTest_DualTest ) {#ifdef HAVE_THREAD                thread_start( tempSettings );#else                server->runNext = tempSettings;#endif            } else {                server->runNext =  tempSettings;            }        }        server->reporthdr = InitReport( server );        // Prep for next connection        if ( !isSingleClient( mSettings ) ) {            mClients--;        }        Settings_Copy( mSettings, &server );        server->mThreadMode = kMode_Server;    } while ( !sInterupted && (!mCount || ( mCount && mClients > 0 )) );    Mutex_Unlock( &clients_mutex );    Settings_Destroy( server );}/* --------------------------------------------------------------------  * Run the server as a daemon   * --------------------------------------------------------------------*/ void Listener::runAsDaemon(const char *pname, int facility) {#ifndef WIN32     pid_t pid;     /* Create a child process & if successful, exit from the parent process */     if ( (pid = fork()) == -1 ) {        fprintf( stderr, "error in first child create\n");             exit(0);     } else if ( pid != 0 ) {        exit(0);     }    /* Try becoming the session leader, once the parent exits */    if ( setsid() == -1 ) {           /* Become the session leader */         fprintf( stderr, "Cannot change the session group leader\n");     } else {    }     signal(SIGHUP,SIG_IGN);     /* Now fork() and get released from the terminal */      if ( (pid = fork()) == -1 ) {        fprintf( stderr, "error\n");           exit(0);     } else if ( pid != 0 ) {        exit(0);     }    chdir(".");     fprintf( stderr, "Running Iperf Server as a daemon\n");     fprintf( stderr, "The Iperf daemon process ID : %d\n",((int)getpid()));     fflush(stderr);     fclose(stdin); #else     fprintf( stderr, "Use the precompiled windows version for service (daemon) option\n"); #endif  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -