2017-01-10 6 views
0

ネットワーキングの練習として、私は、C TCPソケットを使用してネットワーク上の帯域幅を測定するために、iPerfのプリミティブバージョンを作成しようとしています。私は、クライアントとサーバー間の接続を確立し、クライアントからサーバーにデータを送信する時間を入力として受け取るソケットコードを設定しました。私は、このコードがどのように高レベルで動作するのか理解していますが、C++で実装するのに問題があります。特に、接続を終了する前に設定された時間間隔でソケットを介してデータを送信する方法を考え出すことです。私は、クライアントがサーバーへの接続を開き、ユーザーが指定した時間間隔のデータを送信し、そしてこの時間間隔が経過したときに、サーバーにフラグを送信して、データの送信、待機サーバがこのフラグを確認し、その交換中に帯域幅を計算して終了します。私はサーバーがクライアントが接続を開き、データの終わりを示すフラグに気付くまでデータを受信し、クライアントにフラグを受け取った肯定応答を送信し、帯域幅を計算して終了するようにします。ここで私は、クライアント/サーバー用に持ってラフの擬似コードは次のとおりです。Cソケットの帯域幅を測定する

クライアント:

time = userinput(); 
host = userinput(); 
port = userinput(); 

sockaddr_in address; // set host and port of this 

s = socket(AF_INET, SOCK_STREAM, 0); // create TCP socket 
connect(s, &address, sizeof(address)); // connect to the user input address 


char data[256]; // initialize to all 0's 
char finish_flag = 'F'; // send flag to signify data is done being sent 
char ack; // buffer to store server's response to the finished_flag 
int bytes_sent = 0; // counter for how much data is sent 

while (time_interval) { 
    send(s, data, 256, 0); 
    bytes_sent += 256; 
} 

send(s, &finished_flag, 1, 0); // let the server know data is done being sent 

recv(s, &ack, 1, MSG_WAITALL); // wait for the server's acknowledgement 

bandwidth = (bytes_sent/time_interval); // use actual time socket was open for, not user input time 

サーバー:私はソケットを設定するための作業コードを持っていますが、時に混乱しています

port = userinput(); 


sockaddr_in address; // set host and port of this 

s = socket(AF_INET, SOCK_STREAM, 0); // create TCP socket 
listen(s, 1); // listen for 1 connection, the client 
int sock = accept(s, &address, sizeof(address)); // accept connection from the client 

char data[256]; // buffer to receive data in 
char finish_flag = 'F'; // flag to look for 
char ack; // ack flag to send back to client 
int bytes_rec = 0; // counter for how much data is received 

while (no finish_flag received) { 
    recv(sock, &data, 256, MSG_WAITALL); 
    bytes_rec += 256; 
    // keep track of time interval somehow 
} 

send(sock, &ack, 1, 0); 

bandwidth = (bytes_rec/time_interval); 

C++で送受信機能を実装する方法と、サーバーとクライアントの両方で時間間隔を追跡する方法について説明します。私はC++でタイマークラスを調べるべきかどうか、あるいは設定された時間などのためにデータを送信するためのソケットを設定する方法があるかどうかはわかりません。

答えて

0

最初に必要なことは、現在の時間を返す関数であり、測定のニーズに十分な粒度で十分です。

long nowMilliSeconds = myClockFunction(); 
long sendUntilThisTime = nowMilliseconds + (5*1000); // stop sending after 5 seconds 
while(myClockFunction() < sendUntilThisTime) 
{ 
    // send some more data! 
} 

ので、次の質問はmyClockFunctionを(実装する方法です):あなたがいることを持っていた場合、その後、あなたの送信ループは、このようなものを見ることができます。新しいバージョンのC++では、std :: chronoには使用できるいくつかの関数があると私は信じています。 times()や他のOS固有のクロックAPI(使用しているOSによって異なる)のようなPOSIX呼び出しを使うことができます。

受信側では、受信コードはすべてのデータを受信したタイミングを知る必要がありますが、終了フラグの長さが1バイトで受信機が常にブロックを受信するのを待っている場合256バイトであれば、送信者はfinish-flagを送信し、受信者はそれを受信しますが、他の255バイトを待つことになり、応答を返すことはありません。最も簡単な解決策は、finish-flagを256バイト長にすることです。受信側は今のように動作しますが、256バイトの各バッファを受信した後、バッファの内容をチェックしてこのバッファがfinish-flagか通常のテストデータかを確認します。あるいは、レシーバに256の代わりに一度に1バイトしか読み込ませることはできませんが、recv()を256回頻繁に呼び出さなければならないため、少し効率が悪くなります。

関連する問題