C++ 原始ICMP套接字:recvfrom()未接收任何数据

C++ 原始ICMP套接字:recvfrom()未接收任何数据,c++,windows,sockets,raw-sockets,C++,Windows,Sockets,Raw Sockets,以下代码是一个用于发送ICMP回显请求和接收回复的程序 /* Forgive my lack of error handling :) */ SOCKET ASOCKET = INVALID_SOCKET; struct sockaddr saddr; struct sockaddr_in *to = (struct sockaddr_in *) &saddr; struct sockaddr_in from; int fromsize = sizeof(from); std::

以下代码是一个用于发送ICMP回显请求和接收回复的程序

/*
    Forgive my lack of error handling :)
*/
SOCKET ASOCKET = INVALID_SOCKET;
struct sockaddr saddr;
struct sockaddr_in *to = (struct sockaddr_in *) &saddr;
struct sockaddr_in from;
int fromsize = sizeof(from);
std::string ip = "[arbitrary ip address]";

struct ICMP {
    USHORT type;
    USHORT code;
    USHORT cksum;
    USHORT id;
    USHORT seq;
}*_ICMP;

char sendBuffer[sizeof(struct ICMP)];
char recvBuffer[256];

WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);

memset(&saddr, NULL, sizeof(saddr));
ASOCKET = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

//  Configure timeout
DWORD timeoutmilsec = 3000;
setsockopt(ASOCKET, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeoutmilsec, sizeof(timeoutmilsec));

to->sin_family = AF_INET;
inet_pton(AF_INET, ip.c_str(), &(to->sin_addr));

_ICMP = new ICMP();

_ICMP->type = 8;
_ICMP->code = 0;
_ICMP->cksum = 0;
_ICMP->id = rand();
_ICMP->seq++;
// I have omitted my declaration of checksum() for simplicity
_ICMP->cksum = checksum((u_short *)_ICMP, sizeof(struct ICMP));

memcpy(sendBuffer, _ICMP, sizeof(struct ICMP));

if (sendto(ASOCKET, sendBuffer, sizeof(sendBuffer), NULL, (sockaddr *)&saddr, sizeof(saddr)) == SOCKET_ERROR)
{
    printf("sendto() failed with error: %u\n", WSAGetLastError());
    return false;
}

if (recvfrom(ASOCKET, recvBuffer, sizeof(recvBuffer), NULL, (sockaddr *)&from, &fromsize) == SOCKET_ERROR)
{
    if (WSAGetLastError() == TIMEOUTERROR)
    {
        printf("Timed out\n\n");
        return false;
    }

    printf("recvfrom() failed with error: %u\n", WSAGetLastError());
    return false;
}
我的问题是,我的
recvfrom()
调用不接收任何数据,并返回TIMEOUTERROR(10060),尽管ping已被回复(Wireshark捕获正在发送的请求和回复)
sendto()
工作正常,但
recvfrom()
的行为异常,我无法找出问题所在


我发现有趣的是,
recvfrom()
只有在网关告诉我无法访问主机时才会接收数据;如果主机可访问并且已响应ping,则不会发生此问题。

问题在于
struct ICMP

ICMP的
类型
代码
应为
无符号字符

ICMP的头应该是8字节,但结构ICMP的大小是10字节

所以应该改为:

struct ICMP {
    unsigned char type;
    unsigned char code;
    USHORT cksum;
    USHORT id;
    USHORT seq;
}*_ICMP;

事实证明,一直以来都是我的防火墙阻止了响应。我的代码中唯一的错误是ICMP结构的大小(cshu提到)


谢谢大家的帮助。

可能是Windows防火墙阻止了数据包?