c++ ping包代码
时间: 2023-09-23 15:01:23 浏览: 158
ping命令的C++代码
4星 · 用户满意度95%
c ping包代码是一种用于测试网络连接的代码。它通过发送ICMP(Internet Control Message Protocol)回显请求消息来确定目标主机的可达性和延迟时间。
代码示例如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#include <arpa/inet.h>
#define PACKET_SIZE 4096
// 计算校验和
unsigned short cal_chksum(unsigned short *addr, int len) {
int nleft = len;
int sum = 0;
unsigned short *w = addr;
unsigned short answer = 0;
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
if (nleft == 1) {
*(unsigned char *)(&answer) = *(unsigned char *)w ;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return answer;
}
// 发送ICMP回显请求
void send_ping(int sockfd, struct sockaddr_in *dst_addr) {
struct icmp send_packet;
int packet_len;
bzero(&send_packet, sizeof(send_packet));
send_packet.icmp_type = ICMP_ECHO;
send_packet.icmp_code = 0;
send_packet.icmp_cksum = 0;
send_packet.icmp_id = getpid();
send_packet.icmp_seq = 0;
send_packet.icmp_cksum = cal_chksum((unsigned short*)&send_packet, sizeof(send_packet));
packet_len = sendto(sockfd, &send_packet, sizeof(send_packet), 0, (struct sockaddr*)dst_addr, sizeof(struct sockaddr));
if (packet_len < 0) {
perror("Error sending packet");
exit(1);
}
}
// 接收ICMP回显应答
int recv_ping(int sockfd, struct sockaddr_in *src_addr) {
struct sockaddr_in from;
socklen_t fromlen = sizeof(from);
struct ip *ip;
struct icmp *icmp;
char packet[PACKET_SIZE];
int packet_len;
packet_len = recvfrom(sockfd, packet, sizeof(packet), 0, (struct sockaddr*)&from, &fromlen);
ip = (struct ip*)packet;
icmp = (struct icmp*)(packet + (ip->ip_hl << 2));
if (icmp->icmp_type == ICMP_ECHOREPLY) {
struct timeval end_time;
gettimeofday(&end_time, NULL);
printf("Received reply from %s\t", inet_ntoa(from.sin_addr));
printf("RTT = %ldms\n", (end_time.tv_sec - icmp->icmp_data) * 1000);
return 1;
}
return 0;
}
int main(int argc, char *argv[]) {
int sockfd;
struct sockaddr_in dst_addr;
struct hostent *host;
if (argc < 2) {
printf("Usage: %s <hostname/IP address>\n", argv[0]);
exit(1);
}
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sockfd < 0) {
perror("Error creating socket");
exit(1);
}
host = gethostbyname(argv[1]);
if (host == NULL) {
printf("Unknown host\n");
exit(1);
}
bzero(&dst_addr, sizeof(dst_addr));
dst_addr.sin_family = AF_INET;
memcpy(&dst_addr.sin_addr, host->h_addr, host->h_length);
send_ping(sockfd, &dst_addr);
if (recv_ping(sockfd, &dst_addr)) {
printf("Ping successful\n");
exit(0);
} else {
printf("Ping failed\n");
exit(1);
}
return 0;
}
这段代码使用套接字在网络层发送和接收ICMP回显请求和应答消息。发送方发送一个包含生成的ICMP请求报文的套接字,并计算校验和。接收方接收到响应的报文后,解析报文并根据报文类型和数据信息进行相应的处理。最后,根据是否接收到应答消息来判断网络连接情况。
阅读全文