ループ内でsend
/関数を絞り込むには、どのような方法がありますか。sendto()
ネットワーク用のポート スキャナーを作成していて、2 つの方法を試しましたが、ローカルでしか機能しないようです (自宅のマシンでテストすると機能しますが、別のマシンでテストしようとすると、適切なポート スキャナーを作成したくありません)。スロットル)。
方法 1
/proc/net/dev
私はもともと「送信されたバイト数」属性を解析して読み取り、それに基づいて睡眠時間を計算していました。それはローカルで機能しました(スリープ遅延は帯域幅の流れを調整するために調整されていました)が、別のサーバーでも試してみるとすぐに、/proc/net/dev
データが正しく調整されていないようでした. ローカルでスキャンしているマシンで実行dstat
したところ、多くのデータが高速に出力されていました。
方法 2
次に、送信した合計バイト数を追跡しtotal_sent
、帯域幅スレッドが読み取ってスリープタイマーを計算する変数に追加しようとしました。これはローカルマシンでも機能しましたが、サーバーで試してみると、帯域幅スレッドがスリープを0に減らすように帯域幅スレッドがチェックするたびに1〜2個のパケットしか送信されていないとのことでしたがtotal_sent
、0でもtotal_sent
変数は機能しました睡眠時間が減ったため増加しませんでしたが、代わりに同じままでした。
全体として、Linux コンピューターの帯域幅を監視し、各/ソケット呼び出しusleep()
の前後に渡して帯域幅を調整するスリープ時間を計算する方法が必要です。send
sendto()
編集:私が言及するのを忘れていた他のいくつかのことは、マシンのアップロード速度を計算するスピードテスト機能があり、2 つのスレッドがあることです。1 つのスレッドは帯域幅の使用状況に基づいてグローバル スリープ タイマーを調整し、スレッド 2 はパケットをリモート マシンのポートに送信して、ポートが開いているかどうかをテストし、フィンガープリントを作成します (現在、sendto()
これをすべてテストするために で udp パケットを使用しています)。 .
send
を使用して/sendto()
呼び出しの帯域幅スロットリングを実装するにはどうすればよいですかusleep()
。
編集:これが私の帯域幅監視スレッドのコードです。構造体については気にしないでください。データをスレッドに渡す方法にすぎません。
void *bandwidthmonitor_cmd(void *param)
{
int i = 0;
double prevbytes = 0, elapsedbytes = 0, byteusage = 0, maxthrottle = 0;
//recreating my param struct i passed to the thread
command_struct bandwidth = *((command_struct *)param);
free(param);
//set SLEEP (global variable) to a base time in case it was edited and not reset
SLEEP = 5000;
//find the maximum throttle speed in kb/s (takes the global var UPLOAD_SPEED
//which is in kb/s and times it by how much bandwidth % you want to use
//and devides by 100 to find the maximum in kb/s
//ex: UPLOAD_SPEED = 60, throttle = 90, maxthrottle = 54
maxthrottle = (UPLOAD_SPEED * bandwidth.throttle) / 100;
printf("max throttle: %.1f\n", maxthrottle);
while(1)
{
//find out how many bytes elapsed since last polling of the thread
elapsedbytes = TOTAL_BYTES_SEND - prevbytes;
printf("elapsedbytes: %.1f\n", elapsedbytes);
//set prevbytes to our current bytes so we can have results next loop
prevbytes = TOTAL_BYTES_SEND;
//convert our bytes to kb/s
byteusage = 8 * (elapsedbytes / 1024);
//throttle control to make it adjust sleep 20 times every 30~
//iterations of the loop
if(i & 0x40)
{
//adjust SLEEP by 1.1 gain
SLEEP += (maxthrottle - byteusage) * -1.1;//;
if(SLEEP < 0){
SLEEP = 0;
}
printf("sleep:%.1f\n\n", SLEEP);
}
//sleep the thread for a short bit then start the process over
usleep(25000);
//increment variable i for our iteration throttling
i++;
}
}
私の送信スレッドは、テスト用に udp パケットを送信するループ内の単純なsendto()
ルーチンです。は my 、は「A」で埋められた 64 バイトの文字配列であり、isです。while(1)
sock
sockfd
buff
sin
my sockaddr_in
while(1)
{
TOTAL_BYTES_SEND += 64;
sendto(sock, buff, strlen(buff), 0, (struct sockaddr *) &sin, sizeof(sin))
usleep(SLEEP);
}
dstat
ローカル マシンとリモート マシンでの使用状況を確認できるため、ソケット関数が機能することはわかっています。この帯域幅コードはローカル システムで機能します (すべての変数が必要に応じて変更されます) が、経過バイト数でテストしようとしたサーバーでは変更されず (スレッドの反復ごとに常に 64/128 です)、SLEEP
0 までスロットリングされます。理論的には、マシンがパケットをより速く送信できるようにする必要がありますが、SLEEP
経過バイト数が 0 に等しくても 64/128 のままです。sendto()
-1 を返す関数をチェックする if ステートメント内に関数をエンコードしprintf
、エラー コードを -ing して警告しましたが、私が行ったテストにはありませんでした。