gpt4 book ai didi

c - IPv6 客户端无法连接到 IPv6 服务器,无法分配请求的地址

转载 作者:行者123 更新时间:2023-12-04 19:28:19 26 4
gpt4 key购买 nike

重用代码 here重现 tcp 客户端/服务器交互。
服务器初始化正常,开始监听连接。
但是,在运行客户端 ./client ,客户端失败并显示消息

connect(): Cannot assign requested address


链接中的“失败”代码 above (也粘贴在下面)是:
ret = connect(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (ret == -1) {
perror("connect()");
close(sock_fd);
return EXIT_FAILURE;
}
当我运行 ifconfig ,我没有看到 IPv6 地址。这是一个可能的解释吗?我在 OSX 机器上运行 Ubuntu Docker 镜像。
代码很容易编译/运行
gcc server.c -o server
gcc client.c -o client
./server
./client
服务器.c
    #include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>

#define CLIENT_QUEUE_LEN 10
#define SERVER_PORT 7002

int main(void)
{
int listen_sock_fd = -1, client_sock_fd = -1;
struct sockaddr_in6 server_addr, client_addr;
socklen_t client_addr_len;
char str_addr[INET6_ADDRSTRLEN];
int ret, flag;
char ch;

/* Create socket for listening (client requests) */
listen_sock_fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
if(listen_sock_fd == -1) {
perror("socket()");
return EXIT_FAILURE;
}

/* Set socket to reuse address */
flag = 1;
ret = setsockopt(listen_sock_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
if(ret == -1) {
perror("setsockopt()");
return EXIT_FAILURE;
}

server_addr.sin6_family = AF_INET6;
server_addr.sin6_addr = in6addr_any;
server_addr.sin6_port = htons(SERVER_PORT);

/* Bind address and socket together */
ret = bind(listen_sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if(ret == -1) {
perror("bind()");
close(listen_sock_fd);
return EXIT_FAILURE;
}

/* Create listening queue (client requests) */
ret = listen(listen_sock_fd, CLIENT_QUEUE_LEN);
if (ret == -1) {
perror("listen()");
close(listen_sock_fd);
return EXIT_FAILURE;
}

client_addr_len = sizeof(client_addr);

while(1) {
/* Do TCP handshake with client */
client_sock_fd = accept(listen_sock_fd,
(struct sockaddr*)&client_addr,
&client_addr_len);
if (client_sock_fd == -1) {
perror("accept()");
close(listen_sock_fd);
return EXIT_FAILURE;
}

inet_ntop(AF_INET6, &(client_addr.sin6_addr),
str_addr, sizeof(str_addr));
printf("New connection from: %s:%d ...\n",
str_addr,
ntohs(client_addr.sin6_port));

/* Wait for data from client */
ret = read(client_sock_fd, &ch, 1);
if (ret == -1) {
perror("read()");
close(client_sock_fd);
continue;
}

/* Do very useful thing with received data :-) */
ch++;

/* Send response to client */
ret = write(client_sock_fd, &ch, 1);
if (ret == -1) {
perror("write()");
close(client_sock_fd);
continue;
}

/* Do TCP teardown */
ret = close(client_sock_fd);
if (ret == -1) {
perror("close()");
client_sock_fd = -1;
}

printf("Connection closed\n");
}
return EXIT_SUCCESS;
}
客户端.c
    #include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>

#define SERVER_PORT 7002

int main(int argc, char *argv[])
{
int sock_fd = -1;
struct sockaddr_in6 server_addr;
int ret;
char ch = 'a';

/* Arguments could be used in getaddrinfo() to get e.g. IP of server */
(void)argc;
(void)argv;

/* Create socket for communication with server */
sock_fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (sock_fd == -1) {
perror("socket()");
return EXIT_FAILURE;
}

/* Connect to server running on localhost */
server_addr.sin6_family = AF_INET6;
inet_pton(AF_INET6, "::1", &server_addr.sin6_addr);
server_addr.sin6_port = htons(SERVER_PORT);

/* Try to do TCP handshake with server */
ret = connect(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (ret == -1) {
perror("connect()");
close(sock_fd);
return EXIT_FAILURE;
}

/* Send data to server */
ret = write(sock_fd, &ch, 1);
if (ret == -1) {
perror("write");
close(sock_fd);
return EXIT_FAILURE;
}

/* Wait for data from server */
ret = read(sock_fd, &ch, 1);
if (ret == -1) {
perror("read()");
close(sock_fd);
return EXIT_FAILURE;
}

printf("Received %c from server\n", ch);

/* DO TCP teardown */
ret = close(sock_fd);
if (ret == -1) {
perror("close()");
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}

最佳答案

因此,当我在具有基于运行 ifconfig 的 IPv6 地址的非 docker 容器(主机)上运行代码时,我得到输出

Received b from server


这似乎证实了我对容器不支持 IPv6 的怀疑。
如果有人愿意详细说明,欢迎他们。

关于c - IPv6 客户端无法连接到 IPv6 服务器,无法分配请求的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68977059/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com