【问题标题】:C Sockets to Measure Bandwidth用于测量带宽的 C 套接字
【发布时间】:2017-01-10 02:50:28
【问题描述】:

作为一项网络练习,我正在尝试编写 iPerf 的原始版本来使用 C TCP 套接字测量网络上的带宽。我已经设置了套接字代码来建立客户端和服务器之间的连接,并将数据从客户端发送到服务器的时间量作为输入。我理解这段代码应该如何在高层次上工作,但是在 C++ 中实现它时遇到了麻烦,特别是在结束连接之前弄清楚如何在设定的时间间隔内通过套接字发送数据。我希望客户端打开与服务器的连接,在用户指定的时间间隔内发送数据,然后当这个时间间隔结束时,我希望它向服务器发送一个标志,让它知道数据已经发送完毕,等待让服务器确认此标志,然后计算该交换期间的带宽并退出。我希望服务器等待客户端打开连接,接收数据,直到注意到表示数据结束的标志,向客户端发送它收到标志的确认,然后计算带宽并退出。这是我为客户端/服务器提供的粗略伪代码:

客户:

time = userinput();
host = userinput();
port = userinput();

sockaddr_in address; // set host and port of this

s = socket(AF_INET, SOCK_STREAM, 0); // create TCP socket
connect(s, &address, sizeof(address)); // connect to the user input address


char data[256]; // initialize to all 0's
char finish_flag = 'F'; // send flag to signify data is done being sent
char ack; // buffer to store server's response to the finished_flag
int bytes_sent = 0; // counter for how much data is sent

while (time_interval) {
    send(s, data, 256, 0);
    bytes_sent += 256;
}

send(s, &finished_flag, 1, 0); // let the server know data is done being sent

recv(s, &ack, 1, MSG_WAITALL); // wait for the server's acknowledgement

bandwidth = (bytes_sent / time_interval); // use actual time socket was open for, not user input time

服务器:

port = userinput();


sockaddr_in address; // set host and port of this

s = socket(AF_INET, SOCK_STREAM, 0); // create TCP socket
listen(s, 1); // listen for 1 connection, the client
int sock = accept(s, &address, sizeof(address)); // accept connection from the client

char data[256]; // buffer to receive data in 
char finish_flag = 'F'; // flag to look for 
char ack; // ack flag to send back to client
int bytes_rec = 0; // counter for how much data is received

while (no finish_flag received) {
    recv(sock, &data, 256, MSG_WAITALL);
    bytes_rec += 256;
    // keep track of time interval somehow
}

send(sock, &ack, 1, 0);

bandwidth = (bytes_rec / time_interval); 

我有设置套接字的工作代码,但在用 C++ 实现发送/接收功能以及如何跟踪服务器和客户端的时间间隔时感到困惑。我不确定是否应该查看 C++ 中的计时器类,或者是否有办法设置套接字以在设定的时间内发送数据等。任何朝着正确方向的推动都将不胜感激!

【问题讨论】:

    标签: c++ sockets tcp bandwidth


    【解决方案1】:

    您需要的第一件事是返回当前时间的函数,其粒度足以满足您的测量需求。如果你有这个,那么你的发送循环可能看起来像这样:

    long nowMilliSeconds = myClockFunction();
    long sendUntilThisTime = nowMilliseconds + (5*1000);  // stop sending after 5 seconds
    while(myClockFunction() < sendUntilThisTime)
    {
        // send some more data!
    }
    

    那么接下来的问题是如何实现myClockFunction()。在较新版本的 C++ 中,我相信 std::chrono 有一些你可以使用的功能;或者,如果您愿意,可以使用诸如 times() 之类的 POSIX 调用,或其他一些特定于操作系统的时钟 API(取决于您使用的操作系统)。

    至于接收方,您的接收代码需要知道它何时接收到所有数据 - 但如果您的完成标志只有一个字节长,并且您的接收器始终等待接收 256 块字节,那么你就有问题了——你的发送者将发送完成标志,你的接收者将收到它,但会继续等待其他 255 个字节,因此永远不会发回任何响应。最简单的解决方案是将完成标志也设为 256 字节长;那么接收器可以像现在一样工作,除了在接收到每个 256 字节的缓冲区之后,它会检查缓冲区的内容,看看这个缓冲区是代表完成标志还是只是正常的测试数据。或者,您可以让接收器一次只读取一个字节而不是 256 个字节,但这会降低效率,因为它必须更频繁地调用 recv() 256 次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-10
      • 2010-09-19
      • 2022-12-08
      • 2021-11-20
      相关资源
      最近更新 更多