如何使用C套接字ping

Joh*_*inz 8 c sockets windows ping icmp

  • 编译器:Code :: Blocks(GNU GCC)
  • 平台:Windows(x86)
  • 包括:winsock.h winsock2.h(ws2_32也链接)

我目前正在尝试编写一个程序,该程序将读取包含IP地址列表的文本文件,并分别ping每个IP地址.如果主机响应ping,则主机的IP地址将被复制到用户指定的借调文件中.不经意的是,这是我第一次使用C的套接字库,我找不到关于如何使用C进行ping的好教程.据我所知,我找到了几个教程.我需要在IP数据报中包含一个ICMP头,它是一个包含ICMP类型,代码和校验和的结构.但我不知道该怎么做,我应该自己声明结构还是在头文件中声明?我假设它在一个标题中但是教程相互矛盾的确切地说明了它的位置.我厌倦了包括icmp.h和netinet/icmp.h,但我的编译器抱怨它们不存在所以我创建了自己的结构.

    struct echo_request
    {
        char type; // Type
        char code; // Code
        short checksum; // Checksum
        short id; // Identification
        short seq; // Sequence
        int time; // Time
        char data[16]; // Data
    };
Run Code Online (Sandbox Code Playgroud)

我认为我可能能够逃脱它,但我甚至无法编译我的程序,因为我的编译器说in_cksum()(校验和生成器)是未定义的.

总结我的问题,我应该包括哪些头文件,如何创建ping数据包,我使用正确的校验和生成器函数,ping是否应该指向端口80,我使用的套接字应该是RAW还是DGRAM?

这是我到目前为止,请注意我故意遗漏了错误检查.

    int socket_descriptor = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

    struct sockaddr_in address; //Initialize address struct
    memset(&address, 0, sizeof(address)); //Clear address struct

    //Declare address
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr(ipaddress);
    address.sin_port = htons(80);

    //Bind socket to address
    bind(socket_descriptor, (struct sockaddr *)&address, sizeof(address));

    //Create packet
    struct echo_request packet; //See above for declaration of struct
    memset(packet.data, 1, 16);
    packet.type = 8; //ECHO_REQUEST
    packet.code = 0;
    packet.time = gettime();
    packet.checksum = 0;
    packet.checksum = in_cksum(packet, sizeof(packet));
Run Code Online (Sandbox Code Playgroud)

Ale*_*lex 5

如果您不必从头开始实施ping并且只需要Windows解决方案,那么我会提出第二个Anton对IcmpSendEcho的建议.如果必须实现ping,请查看POCO ICMP包的实现方式.它是可移植的代码,在Windows上运行良好.

关于具体问题,以下是答案:

我应该包含哪些头文件

#include <winsock2.h>
Run Code Online (Sandbox Code Playgroud)

如何创建ping数据包

有关IPv4数据包的示例,请参阅ICMPv4PacketImpl :: initPacket().

我使用正确的校验和生成器功能

不适用于Windows.有关校验和函数的示例,请参阅ICMPPacketImpl :: checksum().

应该ping到端口80

没有.就ICMP而言,没有端口这样的东西.请参阅ICMP是否使用特定端口?

我使用的插座应该是RAW还是DGRAM

它应该是RAW.