IPv6 TCP клиент, address is not valid in its context
От: Kasumi  
Дата: 17.12.16 12:44
Оценка:
Пишу клиент-серверное приложение, работающее по Ipv6. Сервер биндит сокет к локальному адресу и ждет соединений. Клиент подключается к этому адресу. Когда я запускаю клиент, возникает ошибка "address is not valid in its context" после вызова connect(). Что я делаю не так?

Минимальное работающее и проверяемое приложение:

Сервер

#include <Winsock2.h>
#include <ws2tcpip.h>
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#pragma comment(lib, "Ws2_32.lib")

#define SIO_RCVALL 0x98000001
#define MAX_PACKET_SIZE 0x10000
#define LOCAL_PORT 666
#define MAX_CONNECTIONS 100

void WINAPI FormatError(DWORD errCode);
DWORD WINAPI ClientThread(LPVOID param);
SOCKET WINAPI BindSocket(uint16_t port);

int main()
{
    WSADATA wsadata;
    SOCKET server;
    SOCKET client;
    DWORD ThreadID;
    HANDLE hMutex = NULL;
    sockaddr_in6 client_addr;
    int addr_len = sizeof(client_addr);

    // Initialize winsock2 library
    if (FAILED(WSAStartup(MAKEWORD(2, 2), &wsadata)))
    {
        FormatError(WSAGetLastError());
        goto _end;
    }

    // Create listening socket
    server = BindSocket(LOCAL_PORT);
    if (listen(server, MAX_CONNECTIONS) == SOCKET_ERROR)
    {
        FormatError(WSAGetLastError());
        goto _end;
    }

    // Accept connections
    while (TRUE)
    {
        client = accept(server, (struct sockaddr *)&client_addr, &addr_len);
        printf("Accepted!\n");
        send(client, "hello\r\n", 7, 0);
    }

_end:
    WSACleanup();
    if (hMutex != NULL)
    {
        CloseHandle(hMutex);
    }
}

SOCKET WINAPI BindSocket(uint16_t port)
{
    SOCKET sock = INVALID_SOCKET;
    struct sockaddr_in6 local_addr;
    char ip6_addr_buf[50];

    sock = socket(AF_INET6, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET)
    {
        FormatError(WSAGetLastError());
    }
    else
    {
        RtlZeroMemory(&local_addr, sizeof(local_addr));
        local_addr.sin6_flowinfo = 0;
        local_addr.sin6_family = AF_INET6;
        local_addr.sin6_port= htons(port);
        //local_addr.sin6_addr = in6addr_any;
        inet_pton(AF_INET6, "::1", (void *)&local_addr.sin6_addr.s6_addr);

        if (bind(sock, (struct sockaddr *)&local_addr, sizeof(local_addr)) == SOCKET_ERROR)
        {
            FormatError(WSAGetLastError());
        }
        else
        {
            inet_ntop(AF_INET6, &local_addr.sin6_addr, ip6_addr_buf, sizeof(ip6_addr_buf));
            printf("Server running on port %u address %s...\n", local_addr.sin6_port, ip6_addr_buf);
        }
    }

    return sock;
}

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);
}



Клиент

#include <ws2tcpip.h>
#include <Windows.h>
#include <stdio.h>

#pragma comment(lib, "Ws2_32.lib")

#define REMOTE_HOST "::1"
#define REMOTE_PORT 666
#define PACKET_SIZE 0x1000

void WINAPI FormatError(DWORD errCode);
SOCKET WINAPI ConnectToProxy(char *ip);

int main(int argc, char *argv[])
{
    WSADATA wsadata;
    SOCKET server;

    if (FAILED(WSAStartup(MAKEWORD(2, 2), &wsadata)))
    {
        goto _end;
    }

    server = ConnectToProxy(REMOTE_HOST);

_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;
    int ret = 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)
    {
        DWORD dwError = WSAGetLastError();
        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);
        printf("pton returns: %d\n", ret);
        FormatError(dwError);
        closesocket(sock);
        sock = INVALID_SOCKET;
        goto _end;
    }

_end:
    return sock;
}

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);
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.