Я предоставляю следующее для всех, кто имеет дело с этой или подобными проблемами, когда я сталкивался с этой публикацией, имея дело с чем-то подобным.Я надеюсь, что это сэкономит кому-то еще время.
Я также хочу поблагодарить @Roman R. за его комментарий выше и @ Rom098 за комментарий, указывающий, что изменение размера буфера помогло ему / ейтакже.
Приложение, использующее сокеты Windows с UDP с низкой скоростью передачи данных для передачи данных между несколькими терминалами, работало нормально с Windows XP, но с переходом на Windows 7 у нас начались проблемы с удалением сетевых сообщений..
Архитектура такова, что клиентский терминал ведет диалог с серверным терминалом, отправляя и получая серию UDP-сообщений, при этом клиент поддерживает свое собственное состояние.У клиентского терминала есть поток, клиентский поток, который обрабатывает ввод пользователя и отправку и получение сообщений на серверный терминал.Серверный терминал имеет поток, Серверный поток, который обрабатывает сообщения запроса от других терминалов, а также свой собственный Клиентский поток.Простая последовательность сообщений выглядит следующим образом:
- клиентский терминал отправляет сообщение с запросом на серверный терминал
- серверный терминал отвечает сообщением-подтверждением
- серверный терминал обрабатывает запрос иотправляет ответное сообщение клиенту
- клиентский терминал отправляет подтверждение на серверный терминал
Глядя на комментарии выше, мы проверили с помощью отладчика и обнаружили, что Windows 7 имеет WinSock по умолчанию для полученияи размер буфера отправки 8K (8192 байта).Если посмотреть в Интернете, то, похоже, что Windows XP имела более высокую скорость обработки сетевого трафика.
Мы сделали два изменения в нашем сетевом уровне, которые обрабатывают связь.
Первое - этоиспользуйте функцию setsockopt()
, чтобы удвоить размер буферов приема и отправки, используя следующий код:
iOptLen = sizeof(INT);
error = getsockopt (iSocket, SOL_SOCKET, SO_RCVBUF, (PCHAR)(&iOpt), &iOptLen);
if (error < 0) {
error = WSAGetLastError();
} else if (iOpt < 1024 * 16) {
iOpt = 1024 * 16;
error = setsockopt(iSocket, SOL_SOCKET, SO_RCVBUF, (const PCHAR)(&iOpt), sizeof(iOpt));
if (error < 0) {
error = WSAGetLastError();
}
}
iOptLen = sizeof(INT);
error = getsockopt (iSocket, SOL_SOCKET, SO_SNDBUF, (PCHAR)(&iOpt), &iOptLen);
if (error < 0) {
error = WSAGetLastError();
} else if (iOpt < 1024 * 16) {
iOpt = 1024 * 16;
error = setsockopt(iSocket, SOL_SOCKET, SO_SNDBUF, (const PCHAR)(&iOpt), sizeof(iOpt));
if (error < 0) {
error = WSAGetLastError();
}
}
Второе изменение, которое мы сделали, - это когда клиентский поток ожидает подтверждения и приходит ответное сообщениезатем из серверного терминала обработайте ответное сообщение как комбинацию подтверждения и ответа.То, что мы делаем, предполагаем, что сообщение подтверждения было сброшено в какой-то момент.
С этими двумя изменениями задержка больше не заметна, хотя наши измерения показывают, что иногда сообщение подтверждения от серверного терминала на клиентский терминал все еще продолжаетсяупал.
См. также
Изменить размер буфера сокета по умолчанию в Windows , которая использует изменение реестра Windows, чтобы изменить размер буфера по умолчанию с 8 КБ на что-то другое.
Каков размер буфера отправки сокета в Windows? , который относится к TCP, однако предоставляет дополнительную информацию о setsockopt()
.
Winsock UDP-пакеты отбрасываются? , где обсуждается аналогичная проблема с несколькими ответами, предоставляющими дополнительную информацию.
Замечание по применению: Настройка TCP для Windows 2000 / XP для сетей с высокой пропускной способностью от Innominate.com содержит некоторую интересную информациювозможно, немного устаревший, как я понимаю, что с Windows7 сетевые уровни были переписаны.
Связь в реальном времени по протоколу UDP от Майкла Пэна на codeproject.com содержит довольно много подробностей о технических проблемах с использованием UDP.