Как я могу замедлить TCP-соединение в Windows? - PullRequest
4 голосов
/ 23 февраля 2010

Я занимаюсь разработкой прокси-программы для Windows, в которой моя программа соединяет два сокета TCP, подключенных через разные адаптеры. То есть моя программа читает из одного сокета и пишет в другой, и наоборот. Каждый сокет обрабатывается своим собственным потоком. Когда один сокет читает данные, он ставится в очередь для другого сокета, чтобы записать его. У меня проблема в том случае, когда одна ссылка работает на 100 МБ, а другая работает на 10 МБ. Я читаю данные из ссылки на 100 МБ быстрее, чем могу записать их на ссылку на 10 МБ. Как я могу «замедлить» более быстрое соединение, чтобы оно по существу работало на более медленной скорости соединения? Изменение более быстрой ссылки на более медленную скорость не вариант. --Thanks

Ответы [ 5 ]

8 голосов
/ 23 февраля 2010

Создать очередь фиксированной длины между чтением и записью потоков. Блокировать очередь, когда очередь заполнена, и очередь, если она пуста. Обычный семафор или мьютекс / переменная условия должны работать. Поиграйте с размером очереди, чтобы медленный поток всегда был занят.

6 голосов
/ 23 февраля 2010

Если это проблема, значит, вы пишете программу неправильно.

Вы не можете поместить более 10 Мбит / с на ссылку 10 Мбит / с, поэтому ваш поток, который пишет по более медленной ссылке, должен начать блокироваться при записи. Поэтому, пока ваш поток использует буфер чтения того же размера, что и буфер записи, поток должен потреблять данные только так быстро, как он может выбросить их обратно в канал 10 Мбит / с. Любой контроль потока, необходимый для того, чтобы удаленный отправитель не мог направить вам более 10 Мбит / с в канал 100 Мбит / с, будет автоматически обработан протоколом TCP.

Так что это не должно быть проблемой, если ваши буферы чтения и записи имеют одинаковый размер в этом потоке (или в любом потоке).

4 голосов
/ 23 февраля 2010

Прекратите чтение данных, если вы не можете их записать.

Существует очередь байтов, поступающих в вашу программу по ссылке 100 Мбит / с, и очередь из вашей программы по ссылке 10 Мбит / с. Когда исходящая очередь заполнена, прекратите чтение из входящей очереди и TCP, переставив клиент обратно по каналу 100 Мбит / с.

Вы можете использовать внутреннюю очередь между читателем и записывающим устройством, чтобы реализовать это чисто.

3 голосов
/ 23 февраля 2010

Много сложных и правильных решений были изложены. Но на самом деле, чтобы понять суть вопроса - почему у вас есть две темы? Если бы вы выполняли чтение в сокете-100, запись в сокет-10 в одном потоке, это естественным образом блокировало бы запись, и вам не пришлось бы создавать что-то сложное.

0 голосов
/ 23 февраля 2010

Если вы делаете неблокирование, цикл событий в стиле select (): вызывайте только FD_SET (readSocket, & readSet), если ваша очередь исходящих данных меньше некоторого жестко заданного максимального размера.

Таким образом, когда исходящий сокет отстает, ваш прокси прекратит считывать данные с более быстрого клиента, пока он не перехватит данные. Протокол TCP позаботится обо всем остальном (в частности, он скажет вашему быстрому клиенту на некоторое время замедлиться)

...