0

我编写了一个网络程序作为网络项目的一部分。该程序生成一堆数据包(TCP 用于使用 berkely 套接字 API 进行通信)并将其发送到特定端口并测量它返回的响应。该程序运行良好,但我想做一些后端计算,例如我的程序实际生成的数据速率。我试图做的是我测量了发送数据包的代码例程之前和之后的时间,并将总数据除以那个时间,即:在一次例程中总共发送了 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)); 
}

我想确认我是否正确地解决了这个问题。此外,如果这是正确的方法,是否有办法找出数据包从网络中出来的实际速率,即来自以太网接口的数据包的实际物理速率?我们能否估计一下我在程序中计算的数据包速率(在用户模式下,我希望它在系统调用中遍历用户/内核屏障时会慢很多)和实际数据包速率之间的差异?非常感谢所有帮助。

谢谢。

4

1 回答 1

1

我怀疑这不是你想要的。你所拥有的会给你信息,但可能不是如何改进它的指标。

通常我担心的是测量套接字发送/接收关系中的延迟。这通常涉及测量我在发送()之间花费了多长时间,或者我在某种形式的 recv()中等待了多长时间。

通常有几件事需要注意。您是依靠网络层来收集和缓冲您的发送,还是仅在您希望数据发出时才缓冲和发送?如果是后者,您通常想要关闭 nagle 缓冲(请参阅 setsockopt 和 TCP_NODELAY) - 但请注意代码不会倒退。

接下来是缓冲。您可能正在测量数据到达套接字缓冲所需的时间,这几乎是即时的。如果您正在使用响应数据包的 now ack/coordination 进行流式传输,这将在很长一段时间内平均正常。您可以使用 setsockopt() 和 SO_RCVBUF/SO_SNDBUF 来处理缓冲问题。

我要走得更远一点。如果您正在测量代码而不是物理网络的性能,并且您正在尽可能大的块中发送和接收数据包,那么我通常会检查另外两件事。

  1. 你有一个ACK类型的协议。代码是否基本上以某种模式发送/接收。如果是这样,那么延迟可能是最大的问题。有很多方法可以解决这个问题,从允许多个挂起的请求独立返回,到实现滑动窗口。主要思想是不要阻碍数据流。

  2. 最后,如果您正在处理 recv() ,您通常不想阻塞 recv ,除非您真的只想处理每个线程/进程的一个套接字关系。老派的解决方案是 select(),这对于合理的可扩展性来说仍然是可行的。对于更大规模的解决方案,您可以使用 epoll(linux)、kevents(osx) 或 IOCP(windows)。这些允许您将更多的簿记和(有时)线程池移回操作系统。如果您的问题真的是关于我可以从这个 NIC 中抽取多少数据,那么这就是您想要的地方;但除非您处理多个连接,否则很少需要。

抱歉,如果我错过了您的真正要求,但我试图涵盖常见问题。

于 2012-03-04T19:22:58.907 回答