ipv6编写ping命令出错


#include<iostream>
#include<string.h>
#include<WinSock2.h>
#include<thread>
#include<ws2def.h>
#include<ws2ipdef.h>
#pragma comment(lib,"ws2_32.lib")

// ICMP 报文头
struct icmpHeader {
    unsigned char type; // 类型
    unsigned char code; // 代码
    unsigned short checkSum; // 检验和
    unsigned short id; // 标识符
    unsigned short sequence; // 序列号
};

// 计算检验
unsigned short computeCks(icmpHeader* picmp, int len) {
    long sum = 0;
    unsigned short* pusicmp = (unsigned short*)picmp;
    while (len > 1) {
        sum += *(pusicmp++);
        if (sum & 0x80000000)
            sum = (sum & 0xffff) + (sum >> 16);
        len -= 2;
    }
    if (len)
        sum += (unsigned short)*(unsigned char*)pusicmp;
    while (sum >> 16)
        sum = (sum & 0xffff) + (sum >> 16);
    return (unsigned short)~sum;
}

int ping(const std::string& targetIP) {
    // 初始化套接字库
    WORD wReq = MAKEWORD(2, 2);
    WSADATA wsadata;
    WSAStartup(wReq, &wsadata);
    // 填充服务端地址
    SOCKADDR_IN6 serverAddr;
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin6_family = AF_INET6;
    serverAddr.sin6_addr = inet_addr(targetIP.c_str());

    SOCKET s = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMP);

    // 构造 ICMP 报文
    char sendBuf[8 + 32] = { 0 };
    icmpHeader* pIcmp = (icmpHeader*)sendBuf;
    pIcmp->type = 8;
    pIcmp->code = 0;
    pIcmp->checkSum = 0;
    pIcmp->id = (USHORT)::GetCurrentProcessId();
    pIcmp->sequence = 0;
    // 填充数据部分
    memcpy(sendBuf + 8, "abcdelmnopqrstuvwiammekakuactor", 32);
    // 计算检验和
    pIcmp->checkSum = computeCks((icmpHeader*)sendBuf, sizeof(sendBuf));

    // 发送报文
    DWORD start = GetTickCount64();
    int sendLen = sendto(s, sendBuf, sizeof(sendBuf), 0, (SOCKADDR*)&serverAddr, sizeof(SOCKADDR));
    if (sendLen < 0) printf("errno = %d\n", GetLastError());
    // 接收报文
    char recvBuf[1024];
    SOCKADDR_IN6 fromAddr;
    int fLen = sizeof(fromAddr);
    unsigned timeOut = 1000; // 超时时间
    setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeOut, sizeof(timeOut)); // 设置接收超时
    while (true) {
        int len = recvfrom(s, recvBuf, 1024, 0, (SOCKADDR*)&fromAddr, &fLen);
        if (len < 0) {
            std::cout << "请求超时" << std::endl;
            return INT32_MAX;
        }
        else break;
    }
    DWORD end = GetTickCount64();
    DWORD timeSpan = end - start;

    // 回送报文解析
    char ipInfo = recvBuf[0];
    // ipv4 头部的第 9 个字节为 TTL 的值
    //ipv6 头部的第55个字段为TTL的值
    unsigned char ttl = recvBuf[54];
    int ipHeadLen = ((char)(ipInfo << 4) >> 4) * 4; // IP报文头部长度
    icmpHeader* icmpResp = (icmpHeader*)(recvBuf + ipHeadLen);
    if (icmpResp->type == 0) { //回显应答报文
        printf("来自 %s 的回复:字节=32 时间=%2dms TTL=%d\n",
            targetIP.c_str(), timeSpan, ttl);
        return timeSpan;
    }
    else {
        printf("请求超时。type = %d\n", icmpResp->type);
        return INT32_MAX;
    }
}

int main() {
    std::cout << "请输入目的IP地址:";
    std::string IP;
    std::cin >> IP;
    int maxTime = INT32_MIN, minTime = INT32_MAX, timeSum = 0, acpkgCnt = 0;
    printf("\n正在 Ping %s 具有 32 字节的数据:\n", IP.c_str());
    while (1) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        int timeSpan = ping(IP);
        acpkgCnt += timeSpan != INT32_MAX;
        maxTime = max(maxTime, timeSpan);
        minTime = min(minTime, timeSpan);
        timeSum += timeSpan;
    }
    printf("\n%s 的 Ping 统计信息:\n", IP.c_str());
    printf("    数据包: 已发送 = 4,已接收 = %d,丢失 = %d (%d%% 丢失),\n",
        acpkgCnt, 4 - acpkgCnt, (4 - acpkgCnt) * 100 / 4);
    if (!acpkgCnt) return 0;
    printf("往返行程的估计时间(以毫秒为单位):\n");
    printf("    最短 = %dms,最长 = %dms,平均 = %dms\n", minTime, maxTime, timeSum / acpkgCnt);
}

serverAddr.sin6_addr = inet_addr(targetIP.c_str());
这块报错,其实到这里我也不知道怎么去改。ipv4是可以的 但是ipv6不行。希望指点一下

错误(活动) E0349 没有与这些操作数匹配的 "=" 运算符

错误 C2679 二元“=”: 没有找到接受“unsigned long”类型的右操作数的运算符(或没有可接受的转换)

sin6_addr 是个结构体。 inet_addr的返回值是runsigned long