首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言基礎

C 語言實現 Ping 程序:ICMP 協議與原始套接字詳解

     編輯:C 語言基礎

Ping 原理

發送 ICMP Echo Request(類型 8),目標回應 Echo Reply(類型 0)。測量往返時間(RTT)、TTL、序列號。屬於網絡層協議,無端口概念,使用原始套接字(`SOCK_RAW, IPPROTO_ICMP`)。

關鍵結構

  • IP 頭部:版本、首部長度、服務類型、總長度、標識、標誌/片偏移、TTL、協議(ICMP=1)、首部檢驗和、源/目的 IP。
  • ICMP 頭部:類型、代碼、檢驗和、標識符、序列號、可選數據(時間戳)。

實現步驟

  1. 創建原始套接字 `socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)`(需 root 權限)。
  2. 構造 ICMP 報文:填充類型=8、代碼=0、標識符=PID、序列號遞增、數據填充時間戳,計算校驗和。
  3. `sendto` 發送至目標 IP。
  4. `select`/`recvfrom` 接收回應,超時處理。
  5. 解析回應:驗證類型=0、標識符匹配、序列號匹配,計算 RTT = 當前時間 - 發送時間戳。
  6. 統計發送/接收/丟包率、min/avg/max/mdev RTT。

校驗和計算

unsigned short checksum(void *b, int len) {
    unsigned short *buf = b;
    unsigned int sum = 0;
    for (; len > 1; len -= 2) sum += *buf++;
    if (len == 1) sum += *(unsigned char*)buf;
    sum = (sum >> 16) + (sum & 0xFFFF);
    sum += (sum >> 16);
    return ~sum;
}

難點與注意

  • 原始套接字需管理員權限(Linux `CAP_NET_RAW` 或 root)。
  • ICMP 類型/代碼、IP 頭部長度變化(選項)需正確解析。
  • 多線程/異步可並發 Ping 多目標。

總結

手寫 Ping 是理解網絡協議、原始套接字、校驗和、時間測量的絕佳實踐,代碼約 200 行即可實現核心功能,適合網絡編程教學與面試準備。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved