ttcp测试网络吞吐量

发布于:2024-04-30 ⋅ 阅读:(27) ⋅ 点赞:(0)

计算机网络中的几个性能指标

带宽:用来表示网络的通信线路传送数据的能力,通常是指单位时间内从网络中的某一点通过另一点的最高数据率,即网络设备所支持的最高速度
吞吐量:表示单位时间内通过某个网络(或信道、接口)的数据量。

代码位置及分析

ttcp代码位置:muduo-master/examples/ace/ttcp

ttcp_blocking.cc就是简单的客户端服务端通信(阻塞IO),通信的过程中加入测试的逻辑

客户端主要函数

void transmit(const Options& opt)
{
  struct sockaddr_in addr = resolveOrDie(opt.host.c_str(), opt.port);
  printf("connecting to %s:%d\n", inet_ntoa(addr.sin_addr), opt.port);

  int sockfd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  assert(sockfd >= 0);
  int ret = ::connect(sockfd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr));
  if (ret)
  {
    perror("connect");
    printf("Unable to connect %s\n", opt.host.c_str());
    ::close(sockfd);
    return;
  }

  printf("connected\n");
  muduo::Timestamp start(muduo::Timestamp::now());	// 发送前记录时间
  struct SessionMessage sessionMessage = { 0, 0 };
  sessionMessage.number = htonl(opt.number);
  sessionMessage.length = htonl(opt.length);
  if (write_n(sockfd, &sessionMessage, sizeof(sessionMessage)) != sizeof(sessionMessage))
  {
    perror("write SessionMessage");
    exit(1);
  }

  const int total_len = static_cast<int>(sizeof(int32_t) + opt.length);
  PayloadMessage* payload = static_cast<PayloadMessage*>(::malloc(total_len));
  assert(payload);
  payload->length = htonl(opt.length);
  for (int i = 0; i < opt.length; ++i)
  {
    payload->data[i] = "0123456789ABCDEF"[i % 16];
  }
	// 发送的数据总量
  double total_mb = 1.0 * opt.length * opt.number / 1024 / 1024;
  printf("%.3f MiB in total\n", total_mb);

  for (int i = 0; i < opt.number; ++i)
  {
    int nw = write_n(sockfd, payload, total_len);
    assert(nw == total_len);

    int ack = 0;
    int nr = read_n(sockfd, &ack, sizeof(ack));
    assert(nr == sizeof(ack));
    ack = ntohl(ack);
    assert(ack == opt.length);
  }

  ::free(payload);
  ::close(sockfd);
  // 计算出时间差
  double elapsed = timeDifference(muduo::Timestamp::now(), start);	
  // 数据总量/时间,单位 mb\s
  printf("%.3f seconds\n%.3f MiB/s\n", elapsed, total_mb / elapsed);
}

服务端的主要函数

void receive(const Options& opt)
{
  int sockfd = acceptOrDie(opt.port);

  struct SessionMessage sessionMessage = { 0, 0 };
  if (read_n(sockfd, &sessionMessage, sizeof(sessionMessage)) != sizeof(sessionMessage))
  {
    perror("read SessionMessage");
    exit(1);
  }

  sessionMessage.number = ntohl(sessionMessage.number);
  sessionMessage.length = ntohl(sessionMessage.length);
  printf("receive number = %d\nreceive length = %d\n",
         sessionMessage.number, sessionMessage.length);
  const int total_len = static_cast<int>(sizeof(int32_t) + sessionMessage.length);
  PayloadMessage* payload = static_cast<PayloadMessage*>(::malloc(total_len));
  assert(payload);

  for (int i = 0; i < sessionMessage.number; ++i)
  {
    payload->length = 0;
    if (read_n(sockfd, &payload->length, sizeof(payload->length)) != sizeof(payload->length))
    {
      perror("read length");
      exit(1);
    }
    payload->length = ntohl(payload->length);
    assert(payload->length == sessionMessage.length);
    if (read_n(sockfd, payload->data, payload->length) != payload->length)
    {
      perror("read payload data");
      exit(1);
    }
    int32_t ack = htonl(payload->length);
    if (write_n(sockfd, &ack, sizeof(ack)) != sizeof(ack))
    {
      perror("write ack");
      exit(1);
    }
  }
  ::free(payload);
  ::close(sockfd);
}

还有非阻塞IO版的,也就是ttcp.cc,大部份依照回调函数的方式实现

测试

环境:两条桥联的虚拟机(Centos)

阻塞io

[wang@localhost bin]$./ttcp_blocking -t ip -l 1024000
port = 5001
buffer length = 1024000
number of buffers = 8192
8000.000 MiB in total
40.412 seconds
197.960 MiB/s

非阻塞io

[wang@localhost bin]$ ./ttcp_muduo -t ip -l 1024000
port = 5001
buffer length = 1024000
number of buffers = 8192
INFO  payload bytes 8388608000 - ttcp.cc:69
8000.000 MiB transferred
198.619 MiB/s

两种方式吞吐量差不多


网站公告

今日签到

点亮在社区的每一天
去签到