定数INADDR_ANYは、いわゆるIPv4ワイルドカードアドレスです。 ワイルドカードIPアドレスは、マルチホームホスト上のインターネットソケット をバインドするアプリケーションに役立ちます。マルチホーム ホスト上のアプリケーションがソケットをそのホストのIPアドレスの1つにバインドする場合、その ソケットはUDPデータグラムまたはTCP接続要求のみをそのIPアドレスに送信します( )。しかし、通常、マルチホームホスト のアプリケーションは、ホストのIPアドレスのいずれかを指定するデータグラムまたは接続要求 を受信できるようにし、ソケットを にバインドしてこれを可能にします。質問についてINADDR_ANY
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));
質問>
我々は特定のIPアドレスにソケットをバインドする場合は、ソケットはそのIPアドレスに送信された送信されたUPD/TCP要求を受け取ることができます。
上記のコードで示したように、ソケットserver_sockfdはINADDR_ANYにバインドされました。 ソケットがインターネット上でリクエストを受信できれば、ここでも混乱していると思います。インターネット上のUDP/TCPのリクエストがたくさんあります。もしソケットが誰にでも返ってきたら、 はどうすれば動作するのですか?クライアント側のための
が//更新されたコード//このサーバ/クライアントプログラムの実行方法については、更新され、サーバー側のコード
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");
}
}
//に更新
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);
}
//。
$ ./server_program &
[1] 31047
$ ./client_program ::1 ciao // Send to server on local host
Server received 4 bytes from (::1, 32770)
Response 1: CIAO
@ q0987オペレーティングシステムのネットワークスタックは、何らかの種類の診断モード(「パケットスニッフィング」)が要求されない限り、そのマシンのアドレスの1つではないIPトラフィックをプログラムに配信しません。低レベルおよび/またはスイッチドネットワークでの適切なパケットアドレッシングは、間違ったアドレストラフィックの多くがネットワークスタックのIPレベルと同じくらい高くなることを防ぐでしょう。 –
更新されたクライアント側のコードを参照してください。クライアント側のコードではサーバーのIPアドレスが指定されていません。10.0.0.15から10.0.0.16の範囲のIPは指定しません。次に、クライアントがクライアントから要求を送信したことをサーバーがどのように知っていますか? – q0987
@ q0987ネットワーキングスタックについて学ぶのに役立ちます。ネットワーク化されたすべてのマシンは、1つ以上のIPアドレスを持つことができます。これらのIPアドレスの1つに向けられたトラフィックにのみ応答します。マジックアドレス0.0.0.0は単に "このマシンが責任を持つIPアドレスのどれか"を意味します。 –