В главе 60 список исходных кодов
id_echo.h
/*************************************************************************\
* Copyright (C) Michael Kerrisk, 2018. *
* *
* This program is free software. You may use, modify, and redistribute it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation, either version 3 or (at your option) any *
* later version. This program is distributed without any warranty. See *
* the file COPYING.gpl-v3 for details. *
\*************************************************************************/
/* Listing 60-1 */
/* id_echo.h
Header file for id_echo_sv.c and id_echo_cl.c.
*/
#include "inet_sockets.h" /* Declares our socket functions */
#include "tlpi_hdr.h"
#define SERVICE "echo" /* Name of UDP service */
#define BUF_SIZE 500 /* Maximum size of datagrams that can
be read by client and server */
id_echo_sv.c
/*************************************************************************\
* Copyright (C) Michael Kerrisk, 2018. *
* *
* This program is free software. You may use, modify, and redistribute it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation, either version 3 or (at your option) any *
* later version. This program is distributed without any warranty. See *
* the file COPYING.gpl-v3 for details. *
\*************************************************************************/
/* Listing 60-2 */
/* id_echo_sv.c
This program implements a daemon that provides the UDP "echo" service. It
reads datagrams and then sends copies back to the originating address.
NOTE: this program must be run under a root login, in order to allow the
"echo" port (7) to be bound. Alternatively, for test purposes, you can edit
id_echo.h and replace the SERVICE name with a suitable unreserved port
number (e.g., "51000"), and make a corresponding change in the client.
See also id_echo_cl.c.
*/
#include <syslog.h>
#include "id_echo.h"
#include "become_daemon.h"
int
main(int argc, char *argv[])
{
int sfd;
ssize_t numRead;
socklen_t len;
struct sockaddr_storage claddr;
char buf[BUF_SIZE];
char addrStr[IS_ADDR_STR_LEN];
if (becomeDaemon(0) == -1)
errExit("becomeDaemon");
sfd = inetBind(SERVICE, SOCK_DGRAM, NULL);
if (sfd == -1) {
syslog(LOG_ERR, "Could not create server socket (%s)", strerror(errno));
exit(EXIT_FAILURE);
}
/* Receive datagrams and return copies to senders */
for (;;) {
len = sizeof(struct sockaddr_storage);
numRead = recvfrom(sfd, buf, BUF_SIZE, 0,
(struct sockaddr *) &claddr, &len);
if (numRead == -1)
errExit("recvfrom");
if (sendto(sfd, buf, numRead, 0, (struct sockaddr *) &claddr, len)
!= numRead)
syslog(LOG_WARNING, "Error echoing response to %s (%s)",
inetAddressStr((struct sockaddr *) &claddr, len,
addrStr, IS_ADDR_STR_LEN),
strerror(errno));
}
}
id_echo_cl.c
/*************************************************************************\
* Copyright (C) Michael Kerrisk, 2018. *
* *
* This program is free software. You may use, modify, and redistribute it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation, either version 3 or (at your option) any *
* later version. This program is distributed without any warranty. See *
* the file COPYING.gpl-v3 for details. *
\*************************************************************************/
/* Listing 60-3 */
/* id_echo_cl.c
A client for the UDP "echo" service. This program sends each of its
command-line arguments as a datagram to the server and echoes the
contents of the datagrams that the server sends in response.
See also id_echo_sv.c.
*/
#include "id_echo.h"
int
main(int argc, char *argv[])
{
int sfd, j;
size_t len;
ssize_t numRead;
char buf[BUF_SIZE];
if (argc < 2 || strcmp(argv[1], "--help") == 0)
usageErr("%s host msg...\n", argv[0]);
/* Construct server address from first command-line argument */
sfd = inetConnect(argv[1], SERVICE, SOCK_DGRAM);
if (sfd == -1)
fatal("Could not connect to server socket");
/* Send remaining command-line arguments to server as separate datagrams */
for (j = 2; j < argc; j++) {
len = strlen(argv[j]);
if (write(sfd, argv[j], len) != len)
fatal("partial/failed write");
numRead = read(sfd, buf, BUF_SIZE);
if (numRead == -1)
errExit("read");
printf("[%ld bytes] %.*s\n", (long) numRead, (int) numRead, buf);
}
exit(EXIT_SUCCESS);
}
мой вопрос:*
Если я изменю localhost на 127.0.0.1, все идет хорошо.В третьей строке 1988 / id_echo_sv работает хорошо, я не понимаю, почему это происходит, при использовании функции чтения localhost не удалось в клиентском коде.
[root@centos7-10 sockets]# netstat -nupl | grep 7
udp 0 0 0.0.0.0:5353 0.0.0.0:* 874/avahi-daemon: r
udp 0 0 127.0.0.1:323 0.0.0.0:* 884/chronyd
udp 0 0 0.0.0.0:7 0.0.0.0:* 1988/id_echo_sv
udp 0 0 0.0.0.0:35873 0.0.0.0:* 874/avahi-daemon: r
udp 0 0 192.168.122.1:53 0.0.0.0:* 1782/dnsmasq
udp 0 0 0.0.0.0:67 0.0.0.0:* 1782/dnsmasq
из-за функции inetBind () и т. Д. Используйте авторверсия, поэтому, если вы хотите запустить, необходимо загрузить исходный код в tlpi
Если у вас есть идеи, пожалуйста, дайте мне знать, спасибо заранее.