有哪些方法可以尝试在循环内限制send
/函数。sendto()
我正在为我的网络创建一个端口扫描仪,我尝试了两种方法,但它们似乎只在本地工作(当我在我的家用机器上测试它们时它们工作,但是当我尝试在另一台机器上测试它们时它不想创建适当的油门)。
方法一
我最初是/proc/net/dev
在“发送的字节数”属性中解析和读取的,并以此为基础。这在本地有效(睡眠延迟正在调整以调整带宽流),但是当我在另一台服务器上尝试它时,/proc/net/dev
它似乎也没有正确调整数据。我dstat
在一台本地扫描的机器上运行,它正在快速输出大量数据。
方法二
然后,我尝试跟踪我发送的总字节数,并将其添加到total_sent
我的带宽线程将读取并计算睡眠计时器的变量中。这也适用于我的本地机器,但是当我在服务器上尝试它时,它说每次我的带宽线程检查total_sent
使我的带宽线程将睡眠减少到 0 时它只发送 1-2 个数据包,但即使在 0 时total_sent
变量确实由于睡眠时间减少而不会增加,而是保持不变。
总的来说,我想要一种方法来监视 Linux 计算机的带宽并计算我可以在每个/套接字调用usleep()
之前或之后传递的睡眠时间,以限制带宽。send
sendto()
编辑:我忘了提到的其他一些事情是我确实有一个速度测试功能来计算机器的上传速度,并且我有 2 个线程。1个线程根据带宽使用情况调整全局睡眠计时器,线程2将数据包发送到远程机器上的端口以测试它们是否打开并对其进行指纹识别(现在我只是使用带有a的udp数据包sendto()
来测试这一切) .
如何使用. 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()
例程。is my ,是一个 64 字节的字符数组,用“A”填充,并且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 elapsedbytes 仍然是 64/128。我还在sendto()
if 语句中对函数进行了编码,检查返回 -1 的函数并通过printf
-ing 错误代码来提醒我,但在我所做的测试中没有一个。