У меня есть клиент и сервер для протокола IPv6. Я хочу подключить клиента к серверу, но у меня не получается. Возникает ошибка The requested address is not valid in its context. В чем здесь проблема? Я погуглил примеры кода и нашел их совсем немного, но в них подключение к серверу выполняется как у меня.
Код:
#include <ws2tcpip.h>
#include <Windows.h>
#include <stdio.h>
#include "ip.h"
#pragma comment(lib, "Ws2_32.lib")
#define REMOTE_HOST "::1"
#define REMOTE_PORT 666
#define PACKET_SIZE 0x1000
void WINAPI FormatError(DWORD errCode);
DWORD WINAPI HandleConnection(SOCKET sock);
SOCKET WINAPI ConnectToProxy(char *ip);
BOOL WINAPI RecvPacket(SOCKET sock, DWORD *dwBytesRead);
void WINAPI PrintIpHeader (char* buffer);
void WINAPI PrintTcpPacket(char* buffer, int size);
void WINAPI PrintUdpPacket(char *buffer, int size);
void WINAPI PrintIcmpPacket(char* buffer, int size);
void WINAPI PrintData (char* data , int size);
void WINAPI PrintPacket(char* buffer, int size);
int main(int argc, char *argv[])
{
WSADATA wsadata;
SOCKET server;
if (FAILED(WSAStartup(MAKEWORD(2, 2), &wsadata)))
{
goto _end;
}
// Адрес прокси, к которому подключается, задается как константа
// или берется из первого командной строки
// Закомментировать/раскомментировать нужную строку
//server = ConnectToProxy(argv[1]);
server = ConnectToProxy(REMOTE_HOST);
if (server != INVALID_SOCKET)
HandleConnection(server);
_end:
WSACleanup();
}
SOCKET WINAPI ConnectToProxy(char *ip)
{
struct sockaddr_in6 remote_addr;
SOCKET sock = INVALID_SOCKET;
char ip6_addr_buf[100];
sock = socket(AF_INET6, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
goto _end;
}
remote_addr.sin6_flowinfo = 0;
remote_addr.sin6_family = AF_INET6;
inet_pton(AF_INET6, ip, &remote_addr.sin6_addr);
remote_addr.sin6_port = htons(REMOTE_PORT);
if (connect(sock, (struct sockaddr *)&remote_addr, sizeof(remote_addr)) == SOCKET_ERROR)
{
inet_ntop(AF_INET6, &remote_addr.sin6_addr, ip6_addr_buf, sizeof(ip6_addr_buf));
printf("Connection to %s port %u failed\n", ip6_addr_buf, remote_addr.sin6_port);
FormatError(WSAGetLastError());
closesocket(sock);
sock = INVALID_SOCKET;
goto _end;
}
_end:
return sock;
}
// Форматированный вывод ошибок.
// errCode - значение, возвращенное WSAGetLastError()
void WINAPI FormatError(DWORD errCode)
{
char error[1000];
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
errCode,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
error, sizeof(error), NULL);
printf("\nError: %s\n", error);
}
// Получение пакета из сокета. buffer - куда считываем, dwBufSize - размер буфера,
// dwBytesRead - количество прочитанных байт
BOOL WINAPI RecvPacket(SOCKET sock, char *buffer, DWORD dwBufSize, DWORD *dwBytesRead)
{
// Читаем данные
int bytes_read = recv(sock, buffer, dwBufSize, 0);
*dwBytesRead = (bytes_read > 0) ? bytes_read : 0;
// Вернем успех или неудачу
return (bytes_read > 0) ? TRUE : FALSE;
}
// Обработка соединения с прокси
DWORD WINAPI HandleConnection(SOCKET sock)
{
char packet[PACKET_SIZE];
DWORD dwBytesRead = 0;
while (TRUE)
{
RecvPacket(sock, packet, PACKET_SIZE, &dwBytesRead);
PrintPacket(packet, dwBytesRead);
}
}
inet_pton() возвращает 1 и не переустанавливает last error.