Если у вас есть какой-то контроль над хостом назначения, один из способов, с помощью которого вы можете периодически проверять наличие хоста без использования эфемерных портов, - отправлять дейтаграмму UDP и ждать ответа ICMP, сообщающего вам, что датаграмма была отклонена хостом.
Это делается путем создания сокета SOCK_DGRAM, привязки к локальному порту и вызова sendto () для отправки на известный удаленный порт, который не прослушивает. Затем вы можете опрашивать и вызывать recvfrom (), что должно выдать ошибку, если ваш хост получил ответ ICMP. Если хост не подключен, вы не получите ответ. Вы можете повторно использовать один и тот же сокет с тем же портом, чтобы периодически отправлять столько дейтаграмм, сколько требуется.
Для отправки эхо-запроса ICMP требуются высокие привилегии в большинстве систем, поэтому сделать это напрямую из вашего кода сложно.
Вот пример кода, который примерно соответствует тому, что я описываю:
struct sockaddr_in local_address;
struct sockaddr_in remote_address;
int sfd;
char * remote_host;
int s;
fd_set fds;
struct timeval timeout;
remote_host = argv[1];
sfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sfd < 0) {
perror("socket");
}
memset(&local_address, 0, sizeof(struct sockaddr_in));
local_address.sin_family = AF_INET;
local_address.sin_addr.s_addr = INADDR_ANY;
local_address.sin_port = htons(6799);
s = bind(sfd,
(struct sockaddr*)&local_address,
sizeof(local_address));
if (s != 0) {
perror("bind");
exit(1);
}
memset(&remote_address, 0, sizeof(struct sockaddr_in));
remote_address.sin_family = AF_INET;
remote_address.sin_addr.s_addr = inet_addr(remote_host);
remote_address.sin_port = htons(6799);
s = sendto(sfd,
"MSG",
3,
0,
(struct sockaddr*)&remote_address,
sizeof(remote_address));
if (s != 3) {
perror("sento");
exit(1);
}
FD_ZERO(&fds);
FD_SET(sfd, &fds);
timeout.tv_sec = 5;
timeout.tv_usec = 0;
s = select(sfd + 1, &fds, 0, 0, &timeout);
if (s == 1) {
char buf[512];
printf("Got data, host is up\n");
s = recvfrom(sfd, &buf[0], 512, 0, 0, 0);
perror("recvfrom");
} else {
printf("Timeout, host is down\n");
}