繁体   English   中英

为什么将TCP数据包发送到本地主机需要这么长时间?

[英]Why does it take so long to send TCP packets to localhost?

我写了一个简单的C ++客户/服务器对。 服务器只是在套接字接受上派生一个进程,然后等待来自客户端的数据包,然后以另一个数据包进行响应。 客户端只是向服务器发送一个数据包,然后等待答复。 在发送之前和接收之后,我在客户端中都有计时代码。

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

在我看来,延迟的中位数似乎是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);

对于可能甚至从未离开内核缓冲区的内容,2ms当然听起来很高。 我怀疑用于时间戳的功能实际上可能不正确。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM