为什么将TCP数据包发送到localhost需要这么长时间?

时间:2014-02-26 17:25:19

标签: c++ performance tcp

我写了一个简单的C ++客户端/服务器对。服务器只是在socket接受上分叉进程,然后等待来自客户端的数据包,然后用另一个数据包进行响应。客户端只是将数据包发送到服务器,然后等待回复。我在发送之前和接收之后在客户端中有时间码。

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

在我的时间中,中位潜伏期似乎在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);

1 个答案:

答案 0 :(得分:0)

对于可能从未离开内核缓冲区的东西,2毫秒肯定听起来很高。我怀疑用于时间戳的功能实际上可能不准确。