Изменение структур данных для приложений Winsock для IPv6
При добавлении поддержки IPv6 необходимо убедиться, что приложение определяет структуры данных правильного размера. Размер IPv6-адреса гораздо больше, чем IPv4-адрес. Структуры, которые жестко закодируются для обработки размера IPv4-адреса при хранении IP-адреса, вызывают проблемы в приложении и должны быть изменены.
Рекомендации
Лучший подход к обеспечению правильного размера структур заключается в использовании SOCKADDR_STORAGE структуры. Структура SOCKADDR_STORAGE не зависит от версии IP-адреса. Если структура SOCKADDR_STORAGE используется для хранения IP-адресов, IPv4 и IPv6-адреса можно правильно обрабатывать с помощью одной базы кода.
В следующем примере, который является фрагментом файла Server.c, найденного в приложении B, определяется соответствующее использование структуры SOCKADDR_STORAGE . Обратите внимание, что структура, если она используется правильно, как показано в этом примере, корректно обрабатывает адрес IPv4 или IPv6.
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
#define BUFFER_SIZE 512
#define DEFAULT_PORT "27015"
int main(int argc, char **argv)
{
char Buffer[BUFFER_SIZE] = {0};
char *Hostname;
int Family = AF_UNSPEC;
int SocketType = SOCK_STREAM;
char *Port = DEFAULT_PORT;
char *Address = NULL;
int i = 0;
DWORD dwRetval = 0;
int iResult = 0;
int FromLen = 0;
int AmountRead = 0;
SOCKADDR_STORAGE From;
WSADATA wsaData;
ADDRINFO *AddrInfo = NULL;
ADDRINFO *AI = NULL;
// Parse arguments
if (argc >= 1) {
Hostname = argv[1];
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
From.ss_family = (ADDRESS_FAMILY) Family;
//...
return 0;
}
Примечание.
Структура SOCKADDR_STORAGE является новой для Windows XP.
Код, чтобы избежать
Как правило, многие приложения использовали структуру sockaddr для хранения независимых от протокола адресов или структуры sockaddr_in для IP-адресов. Ни структура sockaddr, ни структура sockaddr_in достаточно велика, чтобы хранить IPv6-адреса, и поэтому оба недостаточно, если приложение должно быть совместимо с IPv6.
Задача программирования
Изменение существующей базы кода с IPv4 на IPv4-и IPv6-взаимодействие
- Получите программу Checkv4.exe. Эта программа включена в пакет SDK для Microsoft Windows.
- Запустите программу Checkv4.exe в коде. Узнайте, как запустить программу Checkv4.exe для файлов в разделе "Использование служебной программы Checkv4.exe".
- Программа оповещает об использовании структуры sockaddr или sockaddr_in и предоставляет рекомендации по замене структуры , совместимой с IPv6, SOCKADDR_STORAGE.
- Замените все такие экземпляры и связанный код соответствующим образом, чтобы использовать SOCKADDR_STORAGE структуру.
Кроме того, вы можете искать базу кода для экземпляров структуры sockaddr и sockaddr_in , а также изменить все такое использование (и другой связанный код, по мере необходимости) на структуру SOCKADDR_STORAGE .
Примечание.
Структуры addrinfo и SOCKADDR_STORAGE включают члены семейства протоколов и адресов (ai_family и ss_family), соответственно. RFC 2553 указывает элемент ai_family addrinfo как int, а ss_family указывается в качестве короткого; например, прямая копия между этими элементами приводит к ошибке компилятора.
См. также