📄 client.cpp
字号:
/*--------------------------------------------------------------- * Copyright (c) 1999,2000,2001,2002,2003 * The Board of Trustees of the University of Illinois * All Rights Reserved. *--------------------------------------------------------------- * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software (Iperf) and associated * documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit * persons to whom the Software is furnished to do * so, subject to the following conditions: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and * the following disclaimers. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimers in the documentation and/or other materials * provided with the distribution. * * * Neither the names of the University of Illinois, NCSA, * nor the names of its contributors may be used to endorse * or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ________________________________________________________________ * National Laboratory for Applied Network Research * National Center for Supercomputing Applications * University of Illinois at Urbana-Champaign * http://www.ncsa.uiuc.edu * ________________________________________________________________ * * Client.cpp * by Mark Gates <mgates@nlanr.net> * ------------------------------------------------------------------- * A client thread initiates a connect to the server and handles * sending and receiving data, then closes the socket. * ------------------------------------------------------------------- */#include "headers.h"#include "Client.hpp"#include "Thread.h"#include "SocketAddr.h"#include "PerfSocket.hpp"#include "Extractor.h"#include "delay.hpp"#include "util.h"#include "Locale.h"/* ------------------------------------------------------------------- * Store server hostname, optionally local hostname, and socket info. * ------------------------------------------------------------------- */Client::Client( thread_Settings *inSettings ) { mSettings = inSettings; mBuf = NULL; // initialize buffer mBuf = new char[ mSettings->mBufLen ]; pattern( mBuf, mSettings->mBufLen ); if ( isFileInput( mSettings ) ) { if ( !isSTDIN( mSettings ) ) Extractor_Initialize( mSettings->mFileName, mSettings->mBufLen, mSettings ); else Extractor_InitializeFile( stdin, mSettings->mBufLen, mSettings ); if ( !Extractor_canRead( mSettings ) ) { unsetFileInput( mSettings ); } } // connect Connect( ); if ( isReport( inSettings ) ) { ReportSettings( inSettings ); if ( mSettings->multihdr && isMultipleReport( inSettings ) ) { mSettings->multihdr->report->connection.peer = mSettings->peer; mSettings->multihdr->report->connection.size_peer = mSettings->size_peer; mSettings->multihdr->report->connection.local = mSettings->local; SockAddr_setPortAny( &mSettings->multihdr->report->connection.local ); mSettings->multihdr->report->connection.size_local = mSettings->size_local; } }} // end Client/* ------------------------------------------------------------------- * Delete memory (hostname strings). * ------------------------------------------------------------------- */Client::~Client() { if ( mSettings->mSock != INVALID_SOCKET ) { int rc = close( mSettings->mSock ); WARN_errno( rc == SOCKET_ERROR, "close" ); mSettings->mSock = INVALID_SOCKET; } DELETE_ARRAY( mBuf );} // end ~Clientconst double kSecs_to_usecs = 1e6; const int kBytes_to_Bits = 8; void Client::RunTCP( void ) { long currLen = 0; struct itimerval it; max_size_t totLen = 0; int err; char* readAt = mBuf; // Indicates if the stream is readable bool canRead = true, mMode_Time = isModeTime( mSettings ); ReportStruct *reportstruct = NULL; // InitReport handles Barrier for multiple Streams mSettings->reporthdr = InitReport( mSettings ); reportstruct = new ReportStruct; reportstruct->packetID = 0; lastPacketTime.setnow(); if ( mMode_Time ) { memset (&it, 0, sizeof (it)); it.it_value.tv_sec = (int) (mSettings->mAmount / 100.0); it.it_value.tv_usec = (int) 10000 * (mSettings->mAmount - it.it_value.tv_sec * 100.0); err = setitimer( ITIMER_REAL, &it, NULL ); if ( err != 0 ) { perror("setitimer"); exit(1); } } do { // Read the next data block from // the file if it's file input if ( isFileInput( mSettings ) ) { Extractor_getNextDataBlock( readAt, mSettings ); canRead = Extractor_canRead( mSettings ) != 0; } else canRead = true; // perform write currLen = write( mSettings->mSock, mBuf, mSettings->mBufLen ); if ( currLen < 0 ) { WARN_errno( currLen < 0, "write2" ); break; } totLen += currLen; if(mSettings->mInterval > 0) { gettimeofday( &(reportstruct->packetTime), NULL ); reportstruct->packetLen = currLen; ReportPacket( mSettings->reporthdr, reportstruct ); } if ( !mMode_Time ) { mSettings->mAmount -= currLen; } } while ( ! (sInterupted || (!mMode_Time && 0 >= mSettings->mAmount)) && canRead ); // stop timing gettimeofday( &(reportstruct->packetTime), NULL ); // if we're not doing interval reporting, report the entire transfer as one big packet if(0.0 == mSettings->mInterval) { reportstruct->packetLen = totLen; ReportPacket( mSettings->reporthdr, reportstruct ); } CloseReport( mSettings->reporthdr, reportstruct ); DELETE_PTR( reportstruct ); EndReport( mSettings->reporthdr );}/* ------------------------------------------------------------------- * Send data using the connected UDP/TCP socket, * until a termination flag is reached. * Does not close the socket. * ------------------------------------------------------------------- */ void Client::Run( void ) { struct UDP_datagram* mBuf_UDP = (struct UDP_datagram*) mBuf; long currLen = 0; int delay_target = 0; int delay = 0; int adjust = 0; char* readAt = mBuf;#if HAVE_THREAD if ( !isUDP( mSettings ) ) { RunTCP(); return; }#endif // Indicates if the stream is readable bool canRead = true, mMode_Time = isModeTime( mSettings ); // setup termination variables if ( mMode_Time ) { mEndTime.setnow(); mEndTime.add( mSettings->mAmount / 100.0 ); } if ( isUDP( mSettings ) ) { // Due to the UDP timestamps etc, included // reduce the read size by an amount // equal to the header size // compute delay for bandwidth restriction, constrained to [0,1] seconds delay_target = (int) ( mSettings->mBufLen * ((kSecs_to_usecs * kBytes_to_Bits)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -