2014-02-26 32 views
0

我写了一个简单的C++客户机/服务器对。服务器只是在socket accept上分支一个进程,然后等待来自客户端的数据包,然后用另一个数据包进行响应。客户端只是发送一个数据包到服务器,然后等待回复。我在发送之前和接收之后都有客户端的时间码。为什么发送TCP数据包到localhost需要这么长时间?

我在本地机器上运行服务器和客户机,并将客户机连接到本地主机。

在我的计时中位延迟似乎约为2毫秒。鉴于我没有真正发送任何东西在网络上。 2毫秒的延迟对我来说似乎非常高。

任何人都可以解释为什么我看到如此高的延迟,或者如果这个时间量对于回送地址来说是现实的吗?

我在Linux Ubuntu 12.04上。我直接使用TCP套接字系统调用而不是任何包装(即接受,监听,发送,接收)。

服务器体:

while (1) 
{ 
    ++msgNum; 

    sin_size = sizeof their_addr; 
    new_fd = accept(sockfd, (struct sockaddr*) &their_addr, &sin_size); 
    if (new_fd == -1) 
    { 
     perror("accept"); 
     continue; 
    } 

    inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr*) &their_addr), 
     s, sizeof s); 
    printf("server: got connection from %s\n", s); 

    if (!fork()) 
    { 
     close(sockfd); // child doesn't need the listener 

     MyMsg msg; 
     strcpy(msg.buf, "Hello world"); 

     for (int i = 1; i <= NUM_TEST_MSGS; ++i) 
     { 
      msg.id = i; 

      int numbytes = 0; 
      int bytesRecv = 0; 

      while (numbytes < MSG_LEN) 
      { 
       int sendSize = MSG_LEN - numbytes; 
       if ((bytesRecv = send(new_fd, ((char*) &msg) + numbytes, 
         sendSize, 0)) == -1) 
       { 
        perror("send"); 
        exit(1); 
       } 
       numbytes += bytesRecv; 
      } 

      assert(numbytes == MSG_LEN); 

      //printf("Server sent %d num bytes\n", numbytes); 
     } 

     printf("Server finished sending msgs.\n"); 

     close(new_fd); 
     exit(0); 
    } 
    close(new_fd); 
} 

客户身上:

for (int i = 1; i <= NUM_TEST_MSGS; ++i) 
{ 
    MyMsg msg; 

    int numbytes = 0; 
    int bytesRecv = 0; 

    int start = rdTsc.Rdtsc(); 

    while (numbytes < MSG_LEN) 
    { 
     int recvSize = MSG_LEN - numbytes; 
     if ((bytesRecv = recv(sockfd, ((char*) &msg) + numbytes, recvSize, 0)) == -1) 
     { 
      perror("recv"); 
      exit(1); 
     } 

     numbytes += bytesRecv; 
    } 

    int end = rdTsc.Rdtsc(); 

    perfCounter.Track(end - start); 

    if (numbytes != MSG_LEN) 
    { 
     printf("COMP FAILED: %d %d\n", numbytes, MSG_LEN); 
    } 

    assert(numbytes == MSG_LEN); 

    if (i != msg.id) 
    { 
     printf("Msg %d id %d \n", i, msg.id); 
    } 

    //if (numbytes != MSG_LEN) printf("GOT WEIRD SIZE %d\n", numbytes); 
    assert(msg.id == i); 

    //printf("client: received %d num bytes id %d body '%s'\n", numbytes, msg.id, msg.buf); 

    if (i % 1000 == 0) 
    { 
     printf("Client: Received %d num msgs.\n", i); 
    } 
} 

printf("Client: Finished successfully.\n"); 

close(sockfd); 
+0

如果您发布您的代码,我们可以帮助您更好。 – MrDuk

回答

0

2ms的肯定声音高的东西,甚至可能从未离开内核缓冲区。我怀疑它可能实际上是用于时间戳功能的不准确。

+0

那么我的时间戳使用tsc计数器,而不是任何系统调用。我之前已经将这些计数器用于其他目的。所以我可以排除时间戳。 –

+0

信息有多大?无法一目了然(重复printf()和/或不断打开/关闭),所以我现在到了真正的推测性的东西,如Linux决定阻止而不是增长缓冲区。 – Remy

+0

不是那么大。 1000字节。它是否能够启动? –

相关问题