Question à propos de INADDR_ANY
La constante INADDR_ANY est le soi-disant IPv4 adresse générique. L'
générique de l'adresse IP est utile pour les applications qui se lient Internet
sockets de domaine sur multi-hôtes des hôtes. Si une application sur un multirésident
l'hôte se lie à un socket à l'une de ses hôtes en adresses IP, alors que
socket ne peut recevoir que des datagrammes UDP ou demandes de connexion TCP envoyés
à l'adresse IP. Cependant, normalement, nous voulons une application sur un
multi-hôtes d'accueil pour être en mesure de recevoir des datagrammes ou les demandes de connexion
que spécifier l'hôte en adresses IP, et la liaison du socket
le générique de l'adresse IP de ce fait possible.
struct sockaddr_in server_address;
int server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&server_address, 0, sizeof(struct sockaddr_in));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY); //here is my quesion
server_address.sin_port = htons(9734);
bind(server_sockfd, (struct sockaddr*)&server_address, sizeof(server_address));
Question>
Si nous lier le socket à une adresse IP spécifique, puis le support peut recevoir uniquement les protocoles UDP/TCP demandes envoyées envoyées à l'adresse IP.
Comme je le démontre dans le code ci-dessus, maintenant, la prise server_sockfd est lié avec INADDR_ANY.
Je viens de sentir confus ici b/c si le support peut recevoir toute demande sur internet, comment il peut encore bien travailler. Il ya des tonnes de demandes de TCP/UDP sur internet, si le socket réponses à tout le monde,
comment peut-il encore fonctionner?
//mise à jour du code côté client //
int
main(int argc, char *argv[])
{
struct sockaddr_in6 svaddr;
int sfd, j;
size_t msgLen;
ssize_t numBytes;
char resp[BUF_SIZE];
if (argc < 3 || strcmp(argv[1], "--help") == 0)
usageErr("%s host-address msg...\n", argv[0]);
/* Create a datagram socket; send to an address in the IPv6 somain */
sfd = socket(AF_INET6, SOCK_DGRAM, 0); /* Create client socket */
if (sfd == -1)
errExit("socket");
memset(&svaddr, 0, sizeof(struct sockaddr_in6));
svaddr.sin6_family = AF_INET6;
svaddr.sin6_port = htons(PORT_NUM);
if (inet_pton(AF_INET6, argv[1], &svaddr.sin6_addr) <= 0)
fatal("inet_pton failed for address '%s'", argv[1]);
/* Send messages to server; echo responses on stdout */
for (j = 2; j < argc; j++) {
msgLen = strlen(argv[j]);
if (sendto(sfd, argv[j], msgLen, 0, (struct sockaddr *) &svaddr,
sizeof(struct sockaddr_in6)) != msgLen)
fatal("sendto");
numBytes = recvfrom(sfd, resp, BUF_SIZE, 0, NULL, NULL);
if (numBytes == -1)
errExit("recvfrom");
printf("Response %d: %.*s\n", j - 1, (int) numBytes, resp);
}
exit(EXIT_SUCCESS);
}
//mise a jour pour le serveur de code côté
int
main(int argc, char *argv[])
{
struct sockaddr_in6 svaddr, claddr;
int sfd, j;
ssize_t numBytes;
socklen_t len;
char buf[BUF_SIZE];
char claddrStr[INET6_ADDRSTRLEN];
/* Create a datagram socket bound to an address in the IPv6 somain */
sfd = socket(AF_INET6, SOCK_DGRAM, 0);
if (sfd == -1)
errExit("socket");
memset(&svaddr, 0, sizeof(struct sockaddr_in6));
svaddr.sin6_family = AF_INET6;
svaddr.sin6_addr = in6addr_any; /* Wildcard address */
svaddr.sin6_port = htons(PORT_NUM);
if (bind(sfd, (struct sockaddr *) &svaddr,
sizeof(struct sockaddr_in6)) == -1)
errExit("bind");
/* Receive messages, convert to uppercase, and return to client */
for (;;) {
len = sizeof(struct sockaddr_in6);
numBytes = recvfrom(sfd, buf, BUF_SIZE, 0,
(struct sockaddr *) &claddr, &len);
if (numBytes == -1)
errExit("recvfrom");
/* Display address of client that sent the message */
if (inet_ntop(AF_INET6, &claddr.sin6_addr, claddrStr,
INET6_ADDRSTRLEN) == NULL)
printf("Couldn't convert client address to string\n");
else
printf("Server received %ld bytes from (%s, %u)\n",
(long) numBytes, claddrStr, ntohs(claddr.sin6_port));
for (j = 0; j < numBytes; j++)
buf[j] = toupper((unsigned char) buf[j]);
if (sendto(sfd, buf, numBytes, 0, (struct sockaddr *) &claddr, len) !=
numBytes)
fatal("sendto");
}
}
//mise a jour pour l'exécution de ce serveur/client de programmes.
$ ./server_program &
[1] 31047
$ ./client_program ::1 ciao //Send to server on local host
Server received 4 bytes from (::1, 32770)
Response 1: CIAO
OriginalL'auteur q0987 | 2011-08-01
Vous devez vous connecter pour publier un commentaire.
Il ne reçoit pas de demandes pour chaque adresse IP sur interneta, il reçoit des demandes pour chaque adresse IP de services informatiques. Par exemple, il peut avoir plusieurs cartes, chacune avec une adresse IP distincte ou elle peut avoir une seule carte réseau, capable de gérer plusieurs adresses IP (elle peut même avoir plusieurs cartes, chacune capable de gérer plusieurs adresses IP.
La clé de l'extrait à étudier est:
En d'autres termes, vous pouvez avoir un multi-homed set-up où votre machine services
10.0.0.15
et10.0.0.16
. À l'aide deINADDR_ANY
vous permettra de ramasser le trafic de ces adresses, sans ramasser les demandes de10.0.0.17
qui peut être la machine de l'autre bout du banc (ou de l'autre côté de la planète).Le tableau suivant, avec le haut de la ligne en cours de demande de destinations et de la colonne de gauche étant l'adresse que vous écoutez, indique que vous serez en raison d'une demande (
Y
) ou non (N
):a Il n'a même pas voir la grande majorité des demandes sur le net. La grande majorité ne le font pas même à votre routeur le plus proche (ou même probablement votre fournisseur de services internet). Même ceux qui ne rendre à votre routeur le plus proche de votre machine pourrait ne pas voir si ils sont destinés à une autre machine sur le segment local (promiscuous mode nonobstant).
Veuillez consulter les mises à jour côté client code. Du côté client, le code ne précise pas l'adresse IP du serveur, dans votre cas, il n'est pas spécifier d'adresse ip dans la plage de 10.0.0.15 à 10.0.0.16. Alors comment savoir au serveur que le client envoie une requête à elle?
un socket serveur ne peut pas obtenir le trafic provenant d'un client qui n'a pas de spécifier une adresse IP pour envoyer à (bien qu'il y est une adresse de diffusion qui peut être spécifié). De même, le serveur ne devez spécifier une adresse pour recevoir, mais que l'adresse peut être "l'une des adresses de cet ordinateur"
votre code client t, spécifiez l'adresse du serveur, avec
inet_pton
surargv[1]
. Cet appel prend le format de présentation comme10.0.0.15
et le transforme en un fichier binaire de l'adresse réseau. En d'autres termes, il est transmis sur la ligne de commande. Voir kernel.org/doc/man-pages/online/pages/man3/inet_pton.3.htmlpas tout à fait.
::1
est une adresse IP et que vous ne spécifiez. C'est l'IPv6 équivalent de l'IPv4 127.0.0.1. L'adresse de bouclage (localhost) est pratique pour dire ce courant d'accueil, mais c'est aussi valable qu'une autre adresse IP. C'est presque certainement l'une des adresses IP qui seront desservies par la spécification de INADDR_ANY.OriginalL'auteur paxdiablo