C语言实现ping的代码
时间: 2023-11-28 12:05:36 浏览: 78
C语言实现ping
以下是使用 C 语言实现的 ping 代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
struct icmp_packet
{
struct icmphdr header;
char data[64];
};
void send_packet(int sockfd, struct sockaddr_in address, int seq_num)
{
struct icmp_packet packet;
packet.header.type = ICMP_ECHO;
packet.header.code = 0;
packet.header.un.echo.id = getpid();
packet.header.un.echo.sequence = seq_num;
memset(packet.data, 'A', 64);
if (gettimeofday((struct timeval*) &packet.data, NULL) < 0)
{
perror("gettimeofday");
exit(EXIT_FAILURE);
}
packet.header.checksum = 0;
packet.header.checksum = htons(~(packet.header.checksum + sizeof(packet.header) + sizeof(packet.data)));
if (sendto(sockfd, &packet, sizeof(packet), 0, (struct sockaddr*) &address, sizeof(address)) < 0)
{
perror("sendto");
exit(EXIT_FAILURE);
}
}
void receive_packet(int sockfd, int seq_num, struct sockaddr_in address, int timeout)
{
fd_set descriptors;
FD_ZERO(&descriptors);
FD_SET(sockfd, &descriptors);
struct timeval tv;
tv.tv_sec = timeout;
tv.tv_usec = 0;
char buffer[4096];
struct sockaddr_in sender_address;
socklen_t sender_address_len = sizeof(sender_address);
if (select(sockfd + 1, &descriptors, NULL, NULL, &tv) < 0)
{
perror("select");
exit(EXIT_FAILURE);
}
if (FD_ISSET(sockfd, &descriptors))
{
if (recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*) &sender_address, &sender_address_len) < 0)
{
perror("recvfrom");
exit(EXIT_FAILURE);
}
struct icmphdr* header = (struct icmphdr*) buffer;
if (header->type == ICMP_ECHOREPLY && header->un.echo.id == getpid() && header->un.echo.sequence == seq_num)
{
printf("%d bytes from %s: icmp_seq=%d ttl=%d\n", sizeof(buffer), inet_ntoa(sender_address.sin_addr), seq_num, header->ttl);
}
else
{
printf("Received invalid packet\n");
}
}
else
{
printf("Request timed out\n");
}
}
int main(int argc, char** argv)
{
if (argc != 2)
{
printf("Usage: %s <host>\n", argv[0]);
exit(EXIT_FAILURE);
}
char* host = argv[1];
struct hostent* hostent = gethostbyname(host);
if (!hostent)
{
perror("gethostbyname");
exit(EXIT_FAILURE);
}
struct sockaddr_in address;
address.sin_family = AF_INET;
memcpy(&address.sin_addr, hostent->h_addr_list[0], hostent->h_length);
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sockfd < 0)
{
perror("socket");
exit(EXIT_FAILURE);
}
int seq_num = 1;
while (1)
{
send_packet(sockfd, address, seq_num);
receive_packet(sockfd, seq_num, address, 1);
seq_num++;
sleep(1);
}
return 0;
}
```
阅读全文