2014-02-26 35 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字節。它是否能夠啓動? –

相關問題