用于测量带宽的C套接字

时间:2017-01-10 02:50:29

标签: c++ sockets tcp bandwidth

作为一个网络练习,我试图编写原始版本的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 ++中查看计时器类,或者是否有办法设置套接字以在一定时间内发送数据等。任何正确方向的推动都将是不胜感激!

1 个答案:

答案 0 :(得分:0)

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

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

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

对于接收方,您的接收代码需要知道它何时收到了所有数据 - 但是如果您的结束标志只有一个字节长,而您的接收方总是在等待接收256个块字节,然后你有一个问题 - 你的发送者将发送结束标志,你的接收器将收到它,但将继续等待其他255个字节,因此永远不会发回任何响应。最简单的解决方案是将finish-flag标记为256字节;然后接收器可以像现在一样工作,除了在接收到每个256字节缓冲区之后,它将检查缓冲区的内容以查看该缓冲区是表示结束标志还是仅表示正常的测试数据。或者,您可以让接收器一次只读取一个字节而不是256个,但这样效率会低一些,因为它必须经常调用recv()256次。