我将网络程序编写为网络项目的一部分。该程序生成一堆数据包(用于使用berkely套接字API进行通信的TCP)并将其发送到特定端口并测量它返回的响应。该程序运行得很好,但我想做一些后端计算,比如我的程序实际产生的数据速率。我试图做的是,我测量了代码例程之前和之后的时间,该代码发送数据包并将总数据除以该时间i-e: 一次性发送总共799个数据包,每个数据包为82个字节,所以:
799 x 82 x 8 = 524144位。测量的时间是= 0.0001s所以数据速率,524144 / 0.0001 = 5.24 Gbps
以下是我尝试过的一段代码:
struct timeval start,end;
double diffTime (struct timeval* start, struct timeval* end)
{
double start_sec = ((double) start->tv_sec) + (double) start->tv_usec / 1000000.00;
double end_sec = ((double) end->tv_sec) + (double) end->tv_usec / 1000000.00;
return (end_sec - start_sec);
}
while(1){
gettimeofday(&start, NULL); // getting start time
*/ Call packet sending routine */
gettimeofday(&end, NULL);
printf("Time taken for sending out a batch is %f secs\n", diffTime(&start,&end));
}
我想确认我是否正确地接近了这个问题。另外,如果这是正确的方法,有没有办法找出数据包实际从线路中获取的速率i-e来自以太网接口的数据包的实际物理速率?我们可以估计在程序中计算的数据包速率(在用户模式下,我希望它在系统调用中遍历用户/内核屏障时速度慢得多)和实际数据包速率之间的差异是什么?所有人都非常感激。
感谢。
答案 0 :(得分:1)
我怀疑这不是你想要的。你所拥有的将为你提供信息,但也许不是如何改进它的指标。
通常我担心的是测量套接字发送/接收关系中的挂接延迟。这通常涉及测量我在发送()之间花费多长时间或者在某种形式的recv()中等待多长时间。
通常需要注意几件事。您是依赖于网络层来收集和缓冲您的发送,还是只在您希望数据发布时缓冲和执行发送?如果是后者你通常想关闭nagle缓冲(请参阅setsockopt和TCP_NODELAY) - 但要小心代码不会回退。
接下来是缓冲。您可能正在测量数据达到套接字缓冲所需的时间,这几乎是即时的。如果您正在使用现在的ack /协调响应数据包进行流式处理,这将在很长一段时间内平均得分。使用setsockopt()和SO_RCVBUF / SO_SNDBUF可以搞乱缓冲。
我要走得更远一点。如果您正在测量代码而不是物理网络的perf,并且您正在以尽可能大的块发送和接收数据包,那么我通常会检查两件事。
您有ACK类型协议吗?代码是否基本上以模式发送/ recv。如果是这样,那么延迟可能是最大的问题。有许多方法可以解决这个问题,从允许多个独立流回的待处理请求到实现sliding windows。主要想法就是不要妨碍数据流动。
最后,如果你正在处理recv(),你通常不希望在recv中阻塞,除非你真的只是想要为每个线程/进程处理一个套接字关系。旧学校解决方案是select(),这对于合理的可扩展性仍然可行。对于更大规模的解决方案,您可以选择epoll(linux),kevents(osx)或IOCP(windows)。这些允许您将更多的簿记和(有时)线程池移回操作系统。如果您的问题实际上是关于我可以抽出多少数据,那么这就是您想要的地方;但除非您正在处理多个连接,否则很少需要。
很抱歉,如果我错过了你真正的问题,但我试图解决常见问题。