コード例 #1
0
void PerfSocket::SetSocketOptions( void ) {
  // set the TCP window size (socket buffer sizes)
  // also the UDP buffer size
  // must occur before call to accept() for large window sizes
  set_tcp_windowsize( mSock, mSettings->mTCPWin );

#ifdef IP_TOS

  // set IP TOS (type-of-service) field
  if ( mSettings->mTOS > 0 ) {
    int  tos = mSettings->mTOS;
    Socklen_t len = sizeof(tos);
    int rc = setsockopt( mSock, IPPROTO_IP, IP_TOS,
			 (char*) &tos, len );
    FAIL_errno( rc == SOCKET_ERROR, "setsockopt IP_TOS" );
  }
#endif

  if ( ! mUDP ) {
    // set the TCP maximum segment size
    if(mSettings->mProtocol != IPPROTO_SCTP) {
      setsock_tcp_mss( mSock, mSettings->mMSS );

#ifdef TCP_NODELAY

      // set TCP nodelay option
      if ( mSettings->mNodelay ) {
	int nodelay = 1;
	Socklen_t len = sizeof(nodelay);
	int rc = setsockopt( mSock, IPPROTO_TCP, TCP_NODELAY,
			     (char*) &nodelay, len );
	FAIL_errno( rc == SOCKET_ERROR, "setsockopt TCP_NODELAY" );
      }
#endif
    } else {
      mSettings->mMSS  = getsock_sctp_mss( mSock );

#ifdef SCTP_NODELAY
      // set TCP nodelay option
      if ( mSettings->mNodelay ) {
	int nodelay = 1;
	Socklen_t len = sizeof(nodelay);
	int rc = setsockopt( mSock, IPPROTO_SCTP, SCTP_NODELAY,
			     (char*) &nodelay, len );
	FAIL_errno( rc == SOCKET_ERROR, "setsockopt SCTP_NODELAY" );
      }
#endif
#if defined(SCTP_PARTIAL_DELIVERY_POINT) && defined(SCTP_EXPLICIT_EOR)
      if(mSettings->mEmulation == true) {
	int rc;
	int val=1;
	Socklen_t len = sizeof(int);
	rc = setsockopt( mSock, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
			     (char*) &val, len );
	FAIL_errno( rc == SOCKET_ERROR, "setsockopt SCTP_PARTIAL_DELIVERY_POINT" );
	rc = setsockopt( mSock, IPPROTO_SCTP, SCTP_EXPLICIT_EOR,
			   (char*) &val, len );
	FAIL_errno( rc == SOCKET_ERROR, "setsockopt SCTP_EXPLICT_EOR" );
      }
#endif

    }
  }
}
コード例 #2
0
ファイル: PerfSocket_TCP.cpp プロジェクト: berise/BTools2
void PerfSocket::Client_Recv_TCP(void) {
    // terminate loop nicely on user interupts

    sInterupted = false;
    //my_signal( SIGINT,  Sig_Interupt );
    //my_signal( SIGPIPE, Sig_Interupt );
#ifndef WIN32
    signal (SIGPIPE, SIG_IGN);
#endif

    int currLen;
    InitTransfer();
    double fract = 0.0;
    mStartTime.setnow();
    long  endSize = get_tcp_windowsize(mSock), startSize=endSize, loopLen =0, prevLen =0;
    Timestamp prevTime;
    prevTime.setnow();



    /* Periodic reporting is done here in the loop itself, if Suggest Window Size option is set*/
    mPReporting = false;

    /* Send the first packet indicating that the server has to send data */
    mBuf[0] = 'a';
    currLen = write( mSock, mBuf, mSettings->mBufLen );
    if ( currLen < 0 ) {
        WARN_errno( currLen < 0, "write" );
        return;
    }

    do {
        // perform read
        currLen = read( mSock, mBuf, mSettings->mBufLen );
        mPacketTime.setnow();
        if ( currLen < 0 ) {
            WARN_errno( currLen < 0, "read" );
            break;
        }

        mTotalLen += currLen;
        loopLen +=currLen;

        // periodically report bandwidths
        ReportPeriodicBW();

        double nFract = mStartTime.fraction(mPacketTime,mEndTime);
        if ( nFract > (fract + 0.1) ) {
            printf(seperator_line);
            ReportWindowSize();
            sReporting.Lock();
            ReportBW( loopLen, prevTime.subSec(mStartTime),  mPacketTime.subSec( mStartTime));
            sReporting.Unlock();
            fract +=0.1;
            if ( startSize != endSize ) {
                /* Change the window size only if the data transfer has changed at least by 5% */
                if ( loopLen < prevLen ) {

                    if ( ( ((double)(prevLen - loopLen)) /  
                           ((double)prevLen))  > 0.05         
                       ) {
                        endSize = startSize + (endSize - startSize)/2;
                    }

                } else {
                    if ( ( ((double)(loopLen - prevLen)) /       
                           ((double)prevLen) ) > 0.05          
                       ) {
                        startSize = endSize;
                        endSize = endSize*2;
                        prevLen = loopLen;

                    }
                }
            } else {
                endSize = endSize*2;
                prevLen = loopLen;
            }

            /** Reset the variables after setting new window size */
            prevTime.setnow();
            loopLen = 0 ;
            //shutdown(mSock,SHUT_RDWR);
            close(mSock);
            mSock = -1;
            Connect( mSettings->mHost, mSettings->mLocalhost );
            mBuf[0] = 'a';
            if ( set_tcp_windowsize(mSock,endSize) == -1 ) {
                printf(unable_to_change_win);
            }
            if ( get_tcp_windowsize(mSock) != endSize ) {
                printf(unable_to_change_win);
            }
            write( mSock, mBuf, mSettings->mBufLen );
        }
    } while ( ! (sInterupted  ||
                 (mMode_time   &&  mPacketTime.after( mEndTime ))  ||
                 (!mMode_time  &&  mTotalLen >= mAmount))
            );


    printf( seperator_line );
    ReportWindowSize();
    sReporting.Lock();
    ReportBW( loopLen, prevTime.subSec(mStartTime),  mPacketTime.subSec( mStartTime));
    sReporting.Unlock();

    printf( seperator_line);
    printf( opt_estimate);
    if ( loopLen > prevLen )
        set_tcp_windowsize(mSock,endSize);
    else
        set_tcp_windowsize(mSock,startSize);

    ReportWindowSize();
    printf( seperator_line );

    // stop timing
    mEndTime.setnow();

    sReporting.Lock();
    ReportBW( mTotalLen, 0.0, mEndTime.subSec( mStartTime ));
    sReporting.Unlock();

    if ( mSettings->mPrintMSS ) {
        // read the socket option for MSS (maximum segment size)
        ReportMSS( getsock_tcp_mss( mSock ));
    }
    //close(mSock);
    //mSock = -1;
}