Сетевое программирование не достигло отметки - PullRequest
1 голос
/ 22 марта 2011

Я занимался сетевым программированием с использованием Java и C. До сих пор мне удавалось достигать скорости сети около 15 мегабайт в секунду, используя различные методы и, по-видимому, независимо от размера сообщения по шлейфу, удаленная сеть также дает примерно одинаковая скорость.

Несмотря на это, я использовал iperf для оценки скорости сети, и он достигает 1,6 Гигабайт / сек. Это, очевидно, значительное улучшение. У кого-нибудь есть идеи, как мне добиться такой скорости в практическом программировании?

Ответы [ 3 ]

1 голос
/ 22 марта 2011

Во-первых, числа, которые вы указываете для iperf, звучат неправильно.

1.6Гигабайт / сек = 12.8Гигабит / сек.Это выходит за рамки стандарта 10Gigabit Ethernet.Возможно, вы захотите повторить цифры.

Если с другой стороны у вас есть Gigabit ethernet, то я бы ожидал что-нибудь от 60-100 мегабайт / сек

Основным фактором в Windows являетсябуферы передачи и приема.Если вы увеличите их, вы увидите резкое увеличение производительности.Я не слишком уверен, как вы это делаете в Java.

Под C это делается так (например, буфер 1MegaByte):

int sndbuf_size = 1048575;
result = setsockopt(thesocket, SOL_SOCKET, SO_SNDBUF, &sndbuf_size, sizeof(int));
if (result != -1){
   socklen_t optlen = sizeof(sndbuf_size);
   if (getsockopt(native_socket, SOL_SOCKET, SO_RCVBUF, &sndbuf_size, &optlen) != -1){
        printf("  SO_SNDBUF: %d bytes\n", sndbuf_size);
   }
} else {
   printf("Error setting socket opt SO_SNDBUF (%d)\n", errno);
}

Убедитесь, что вы вызываете это как для отправки, так и дляПолучите буферы до того, как вы вызовете прослушивание или соединение.Примечание: если вы вызовите setsockopt со значением, превышающим максимальное, это не даст сбоя.Чтобы узнать, насколько он велик после вызова, вы должны вызвать getsockopt с той же опцией.

РЕДАКТИРОВАТЬ: Другим узким местом может быть ваш протокол или диск.Однако, если вы просто передаете файлы через сокет с очень небольшими издержками, например, HTTP-сервер, вам следует рассмотреть возможность использования API TransmitFile в Windows или sendfile, если вы используете Linux.

sendfile () копирует данные междуодин дескриптор файла и другой.Поскольку это копирование выполняется в ядре, sendfile () более эффективен, чем комбинация read (2) и write (2), которая потребует передачи данных в пространство пользователя и из него.

Функция TransmitFile используетдиспетчер кэша операционной системы для извлечения данных файла и обеспечения высокопроизводительной передачи данных файла через сокеты.

1 голос
/ 24 марта 2011

Предупреждение: следует плохое искусство ASCII!

Если ваш сетевой шаблон выглядит следующим образом, вы никогда не получите действительно большие скорости:

REQ   REQ   REQ   REQ   REQ
   RSP   RSP   RSP   RSP

Что даст вам отличную скоростьЕсли вы можете достичь этого:

REQ-A REQ-B REQ-C REQ-D REQ-E
     RSP-A RSP-B RSP-C RSP-D RSP-E

Несколько вещей могут привязать вас к первому шаблону.Однопоточный процесс с одним состоянием.Многопоточный процесс с плохо выполненной блокировкой.

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

Выследует стараться избегать использования нового сеанса TCP для каждого запроса / ответа, если можете.Поскольку каждый сеанс TCP ищет свою лучшую скорость, он вызывает сочетание сетевой перегрузки и недостаточного использования.Некоторые новые сетевые протоколы, такие как SCTP, лучше.Параметры протокола HTTP, такие как конвейерная обработка, также хороши.

0 голосов
/ 22 марта 2011

Вы уверены вы получаете 1,6 Гига байт в секунду?Это работает как 13 Гбит / с.Если вы не работаете в коммутаторе основной сети с несколькими оптическими каналами (и каким-то образом управляете генерацией такого большого трафика), я думаю, что-то может быть не так в ваших числах.

...