С розетки для измерения пропускной способности

В качестве сетевого упражнения я пытаюсь написать примитивную версию 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 addresschar 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 ++ или есть ли способ настроить сокет для отправки данных в течение заданного промежутка времени и т. Д. Любой толчок в правильном направлении приветствуется!

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 байтов и, следовательно, никогда не отправит ответ. Самым простым решением было бы сделать флаг финиша длиной 256 байт; тогда получатель мог просто работать так, как работает сейчас, за исключением того, что после получения каждого 256-байтового буфера он проверяет содержимое буфера, чтобы увидеть, представляет ли этот буфер флаг завершения или просто нормальные тестовые данные. В качестве альтернативы вы можете заставить получатель читать только один байт за раз вместо 256, но это будет немного менее эффективно, так как тогда ему придется вызывать recv () в 256 раз чаще.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector