1

私はipv6を使用して単純なtcpサーバークライアントを実行しようとしていました。ipv6とipv4の同じマシンで動作しますが、異なるマシンの場合、ipv6は接続に失敗します。

サーバーコード

int main(int argc, char* argv[])
{
    int sockfd,new_fd,rv,yes=1; 
    struct addrinfo hints,*servinfo,*p; 
    struct sockaddr_storage their_addr;
    socklen_t addr_size;

    SOCKET listenSocket,clientSocket;
    WSADATA w;

    if (WSAStartup(0x0101, &w) != 0)
    {
        fprintf(stderr, "Could not open Windows connection.\n");
        exit(0);
    }

    //ip=argv[1];
    //port=argv[2];

    memset(&hints,0,sizeof(hints));

    hints.ai_family=AF_INET6;
    hints.ai_socktype=SOCK_STREAM;  
    hints.ai_flags=AI_NUMERICHOST;

    if((rv = getaddrinfo("fe80::c0a8:0160","5002",&hints,&servinfo)) != 0)
    {
        perror("\nGetaddrinfo failed\n");
        return 1;
    }   

    //Creating socket   
    listenSocket = socket(servinfo->ai_family,servinfo->ai_socktype,servinfo->ai_protocol);

    if(listenSocket == INVALID_SOCKET)
    {
        printf("\nSocket failed with error \n");
        WSACleanup();
    }

    //setting non blocking mode
    u_long iMode = 1;
    rv = ioctlsocket(listenSocket,FIONBIO,&iMode);

    if(rv == SOCKET_ERROR)
    {
        printf("\nioctl failed\n");
        WSACleanup();
    }

    rv = bind(listenSocket,servinfo->ai_addr,(int)servinfo->ai_addrlen);

    if(rv == SOCKET_ERROR)
    {
        perror("\nBind: \n");
    }

    freeaddrinfo(servinfo);

    rv = listen(listenSocket,SOMAXCONN);

    if(rv == SOCKET_ERROR)
    {
        perror("listen");
        return 1;
    }

    // now accept an incoming connection:


    char recvbuf[DEFAULT_BUFLEN];
    int buflen = DEFAULT_BUFLEN;
    SOCKET AcceptSocket;

    while (1)
    {
        AcceptSocket = SOCKET_ERROR;

        while (AcceptSocket == SOCKET_ERROR)
        {
            AcceptSocket = accept(listenSocket, NULL, NULL);
        }

        printf("Server: Client Connected!\n");
        listenSocket = AcceptSocket;

        rv = recv(listenSocket,recvbuf,buflen,0);
        break;
    }


    printf("Received %d bytes from client \n",rv);  

    closesocket(listenSocket);
    closesocket(AcceptSocket);

    return 0;

}

クライアントコード

int main(int argc,char* argv[])
{
    struct addrinfo hints,*servinfo,*p;
    int rv;
    SOCKET connectSocket;
    WSADATA w;

    if (WSAStartup(0x0101, &w) != 0)
    {
        fprintf(stderr, "Could not open Windows connection.\n");
        exit(0);
    }

    //resetting memory
    memset(&hints,0,sizeof(hints));

    hints.ai_family = AF_INET6;
    hints.ai_socktype = SOCK_STREAM;    
    hints.ai_flags = AI_NUMERICHOST;

    //getting values

    if((rv = getaddrinfo("fe80::c0a8:160","5002",&hints,&servinfo)) != 0)
    {
        perror("Getaddrinfo failed");
        return 1;
    }

    //Creating socket
    connectSocket = socket(servinfo->ai_family,servinfo->ai_socktype,servinfo->ai_protocol);

    if(connectSocket == INVALID_SOCKET)
    {
        perror("Socket create : ");
    }

    rv = connect(connectSocket,servinfo->ai_addr,(int)servinfo->ai_addrlen);
    if(rv == SOCKET_ERROR)
    {
        perror("Socket Connect : ");
    }


    //free memory
    freeaddrinfo(servinfo);


    // Send and receive data.
    int bytesSent;

    char sendbuf[200] = "Client: Sending some test string to server...";
    char recvbuf[200] = "";

    bytesSent = send(connectSocket, sendbuf, strlen(sendbuf), 0);
    printf("Client: send() - Bytes Sent: %ld\n", bytesSent);

    closesocket(connectSocket);
    return 0;
}

目的は、転送されたバイト数を出力することだけです。

4

1 に答える 1

3

リンク ローカル アドレスを使用しているようです。よろしいですか?また、最初にファイアウォールの設定を確認することをお勧めします。

編集: ゾーン ID を含めるようにしてください。コマンドプロンプトで発行すると、ゾーンIDはどこにあるのipconfigかなどのアドレスを取得できるはずです。この回答に従ってリンク ローカル アドレスを使用する場合は重要です。fe80::c0a8:0160%21%21

于 2012-11-08T05:41:22.300 に答える