私は小さなCクライアント/サーバーアプリケーションを作成していますが、外部IPアドレスを使用しているときは接続を確立できません。クライアントとサーバーの両方のためのコードは、クライアントが行う具体的には、hereから取られる:getaddrinfoを使用して外部IPを使用してサーバーに接続する方法は?
char *default_server_name = "localhost";
char *server_name = NULL;
int nport = DEFAULT_DAMA_PORT;
char port[15];
// Parse the command line options
if (parse_options(argc, argv, &server_name, &nport) < 0) {
return -1;
}
if (server_name == NULL) {
server_name = default_server_name;
}
snprintf(port, 15, "%d", nport);
// Connect to the server
int client_socket;
struct addrinfo hints, *servinfo, *p;
int rv;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((rv = getaddrinfo(server_name, port, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
exit(1);
}
for (p=servinfo; p != NULL; p = p->ai_next) {
if ((client_socket = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
#ifdef DEBUG
perror("socket");
#endif
continue;
}
if (connect(client_socket, p->ai_addr, p->ai_addrlen) == -1) {
close(client_socket);
#ifdef DEBUG
perror("connect");
#endif
continue;
}
// Connected succesfully!
break;
}
if (p == NULL) {
// The loop wasn't able to connect to the server
fprintf(stderr, "Couldn't connect to the server\n.");
exit(1);
}
サーバー間:
int nport;
char port[15];
if (parse_options(argc, argv, &nport) < 0) {
return -1;
}
snprintf(port, 15, "%d", nport);
int server_socket;
struct addrinfo hints, *servinfo, *p;
int rv;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if ((rv = getaddrinfo(NULL, port, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
exit(1);
}
for (p=servinfo; p != NULL; p = p->ai_next) {
if ((server_socket = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
#ifdef DEBUG
perror("socket");
#endif
continue;
}
if (bind(server_socket, p->ai_addr, p->ai_addrlen) == -1) {
close(server_socket);
#ifdef DEBUG
perror("bind");
#endif
continue;
}
// We binded successfully!
break;
}
if (p == NULL) {
fprintf(stderr, "failed to bind socket\n");
exit(2);
}
int pl_one, pl_two;
socklen_t pl_one_len, pl_two_len;
struct sockaddr_in pl_one_addr, pl_two_addr;
if (listen(server_socket, 2) < 0) {
fatal_error("Error in syscall listen.", 2);
}
// Get the two clients connections.
pl_one_len = sizeof(pl_one_addr);
pl_one = accept(server_socket,
(struct sockaddr *)&pl_one_addr,
&pl_one_len);
if (pl_one < 0) {
fatal_error("Error in syscall accept.", 3);
}
pl_two_len = sizeof(pl_two_addr);
pl_two = accept(server_socket,
(struct sockaddr *)&pl_two_addr,
&pl_two_len);
if (pl_two < 0) {
fatal_error("Error in syscall accept.", 3);
}
私は、コマンドラインで私のマシンのIPを指定した場合、およびクライアントのserver_name
が151.51.xxx.xxx
のような文字列に設定されていると、ソケットはサーバーに接続できません。あなたが興味を持っている
ホスト名は、ノード名 パラメータに行く:また
127.0.0.1
を使用すると、私はドキュメントが述べているときだと思います同じ動作を示しています。アドレスには、 "www.example.com"のようなホスト名、またはIPv4またはIPv6アドレス(文字列として渡される)のいずれかを指定できます。
ちょうど冗談です。
私は間違って何かしていますか?ファイアウォールなどでクライアントがIPアドレスを使用して接続できないような問題がありますか?
注:私はすでにこの問題のために多くのことを検索したと、一部の人々はまったくgetaddrinfo
を使用して回避し、直接INADDR_ANY
を埋めるために言うが、getaddrinfo
ドキュメントはnodename
としてNULL
を渡すと、すでにINADDR_ANY
と住所を記入しなければならないと述べています新しいメソッドが自動的にこれを行う場合、古いメソッドを使用する必要があるのはわかりません。
サーバー部分が期待通りに機能するには(接続を受け入れるために) 'listen()'と 'accept()'の呼び出しを追加する必要があります。第9.15章と第9.1章をお読みください。 – alk
@alk私は明らかに 'listen'と' accept'を呼び出しています(そうでなければ、クライアントが 'localhost'を' server_name'として使用しているとサーバーはどうなりますか?)。とにかく質問に追加します。 – Bakuriu
サーバはルータの後ろにありますか?必要なポートは開いているか転送していますか? – typ1232