gpt4 book ai didi

c - 如何使用connect()获取内核分配给UDP套接字的本地地址?

转载 作者:行者123 更新时间:2023-12-03 11:52:41 33 4
gpt4 key购买 nike

阅读https://www.amazon.com/Unix-Network-Programming-Sockets-Networking/dp/0131411551 , 章节
8.14 使用 UDP 确定传出接口(interface)

A connected UDP socket can also be used to determine the outgoing interface that willbe used to a particular destination. This is because of a side effect of the connectfunction when applied to a UDP socket: The kernel chooses the local IP address(assuming the process has not already called bind to explicitly assign this). This localIP address is chosen by searching the routing table for the destination IP address, andthen using the primary IP address for the resulting interface.


如果我尝试运行示例(udpcli01.c):
#define BSIZE 256
#define SERV_PORT 9877

typedef struct sockaddr SA;

//argv[1] = ip address
int main(int argc, char **argv)
{
int sockfd;
socklen_t servlen, clilen;
struct sockaddr_in cliaddr, servaddr;
char ip[BSIZE];

if (argc < 2)
{
die("usage: %s <ip>\n", argv[0]);
}

sockfd = socket(AF_INET, SOCK_DGRAM, 0);

servlen = sizeof(servaddr);
memset(&servaddr, 0, servlen);
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

connect(sockfd, (SA *)&servaddr, servlen);

clilen = sizeof(clilen);
if (getsockname(sockfd, (SA *)&cliaddr, &clilen) < 0)
{
perror("getsockname");
}

inet_ntop(AF_INET, &cliaddr, ip, BSIZE);
printf("address %s:%hd\n", ip, cliaddr.sin_port);
}
现在,如果我在一个终端(地址 INADDR_ANY 和端口 9877 )中运行服务器,然后运行上面的客户端:
terminal 1:
$ ./udpserv01

terminal 2:
$ #I will try localhost first
$ ./udpcli01 127.0.0.1
address 2.0.178.211:-11342
$ #did not work, now my host ip 10.0.0.11
$ ./udpcli01 10.0.0.11
address 2.0.193.86:22209
即使客户端在打印其地址和端口之前,我总是会得到一些垃圾,连接到正在监听的服务器。如果我试图打印服务器地址和端口,那么它会起作用(也就是说,它会分别打印 127.0.0.1:987710.0.0.11:9877 -> 我已经尝试过了)。所以我知道 inet_ntop工作正常并获得端口号。那么客户端的问题在哪里呢?内核是否真的在 connect() 上分配地址和端口?根据书?如果是这样,那么为什么我的示例会打印随机垃圾?
uname -a:
Linux Shepherd 5.8.0-36-generic #40-Ubuntu SMP Tue Jan 5 21:54:35 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

最佳答案

您正在传递 struct sockaddr_in 的地址到inet_ntop功能。对于 AF_INET socket 它需要一个指向 struct in_addr 的指针.
所以代替这个:

inet_ntop(AF_INET, &cliaddr, ip, BSIZE);
你要这个:
inet_ntop(AF_INET, &cliaddr.sin_addr, ip, BSIZE);
另外,请务必调用 ntohssin_port成员之前打印它以获得正确的值,并使用 %d而不是 %hd :
printf("address %s:%d\n", ip, ntohs(cliaddr.sin_port));
clilen未正确初始化:
clilen = sizeof(clilen);
它应该是:
clilen = sizeof(cliaddr);

关于c - 如何使用connect()获取内核分配给UDP套接字的本地地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65776191/

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