网络编程培训之六 使用原始套接字实现Ping

本文介绍如何使用原始套接字实现Ping的基本功能,包括返回序列号、TTL和时间等信息。首先理解Ping工具的工作原理,然后探讨原始套接字的使用,并详细解释ICMP报文的结构。程序主要流程是定时发送ICMP请求并接收响应。通过解析IP和ICMP头部信息,可以获取到所需的数据。此外,文章还提到了发送ICMP报文时校验和的计算以及编译运行时可能遇到的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

系列博客参考:http://blog.youkuaiyun.com/zy416548283/article/category/1108400
代码以编号对应放在Github上:https://github.com/zy416548283/networkProgramming

题目

使用原始套接字实现Ping的基本功能,返回序列号、TTL、Time等。

题目解读

  • 首先了解Ping这个工具的用法和功能,我们来man一下:
ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to elicit an ICMP ECHO_RESPONSE from a host or gateway.   
ECHO_REQUEST  datagrams (``pings'')  have  an  IP and ICMP header, followed by a struct timeval and then an arbitrary number of ``pad'' bytes  used  to  fill  out  the
 packet.
  • 了解原始套接字的用法;

  • 了解ICMP报文的数据结构;

  • 设计实现Ping, 原理部分, 可以参考[TCP/IP 详解 卷一]

实现

  • 在TCP/IP协议栈里一般都实现了Ping的服务器,所以我们这里只需要实现一个客户端即可。发送ICMP请求报文,服务器收到之后会返回ICMP响应报文。

  • 程序的主流程是定时发送ICMP请求报文(定时发送是使用SIGALRM信号驱动),并且在原始套接字上循环接收读入的每个分组;并且需要对命令行参数进行处理。

  • 创建原始套接字如下所示:


 sockfd = Socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto);
  • 调用SIGALRM信号处理函数发送第一个分组,并且调用在一秒后产生下一个信号,这个是异步调用
void
sig_alrm(int signo)
{
    (*pr->fsend)();

    alarm(1);
    return;
}
  • 循环接收ICMP消息
for ( ; ; ) {
        msg.msg_namelen = pr->salen;
        msg.msg_controllen = sizeof(controlbuf);
        n = recvmsg(sockfd, &msg, 0);
        if (n < 0) {
            if (errno == EINTR)
                continue;
            else
                err_sys("recvmsg error");
        }

        Gettimeofday(&tval, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值