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。当您发出ipconfig命令提示符时,您应该能够获得区域 IDfe80::c0a8:0160%21所在的地址。根据此答案%21使用链接本地地址时,这一点很重要。

于 2012-11-08T05:41:22.300 回答