c - C UDP套接字连接没有正确分配端口
问题描述
我有以下架构:
program in terminal A (<process 1>):
Stored:
<process 1>: <portnumber 51340>
<process 2>: <portnumber 58432>
program in terminal B (<process 2>):
Stored:
<process 1>: <portnumber 51340>
<process 2>: <portnumber 58432>
所以我在它们之间有一个 UDP 套接字连接来发送和接收一个结构:
int socketID = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in servaddr = {0};
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(0);
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int rc = bind(socketID, (const struct sockaddr *)&servaddr, sizeof(servaddr));
socklen_t sockaddrlen = sizeof(servaddr);
int getsocket = getsockname(socketID, (struct sockaddr *)&servaddr, &sockaddrlen);
在我进行 sendto 之前,我会:
fprintf(stdout, "Using procPort %d\n", idPort);
servaddr.sin_port = htons(<portNumber 58432>);
fprintf(stdout, "Using port %d\n", &toSocketID.sin_port);
sendto(fromSocketID, &msg, sizeof(struct message), 0, (const struct sockaddr *)&toSocketID, toSocketIDLen);
它打印:
Using procPort 58432
Using port 58432
直到这里一切正常。这是问题所在,在我执行 recvfrom 之前,我会这样做:
servaddr.sin_port = htons(<portNumber 58432>);
fprintf(stdout, "Using procPort %d\n", <portNumber 58432>);
fprintf(stdout, "Using port %d\n", servaddr.sin_port);
struct message * recievedMsg = malloc(sizeof(struct message));
recieveResult = recvfrom(socketID, recievedMsg, sizeof(*recievedMsg), 0, (const struct sockaddr *)&servaddr, sizeof(servaddr));
它打印:
Using procPort 58432
Using port 16612
而且它没有收到消息,我认为这是因为端口的神奇变化,即 16612 没有出现在我的程序中的任何位置。但这也可能是因为配置。你看到有什么问题吗?我正在失去理智。
编辑:
你们中的一些人正在争论字节交换。第二部分的其他输出:
Using procPort 50912
Using port 57542
Using procPort 33592
Using port 14467
Using procPort 42115
Using port 33700
解决方案
这些片段很难真正了解全局,但我很确定您的编译器会告诉您问题所在。
struct sockaddr_in servaddr = {0};
...
receiveResult = recvfrom(socketID,
receivedMsg, sizeof(*receivedMsg),
0,
(const struct sockaddr *)&servaddr, sizeof(servaddr));
正如编译器所指出的,您将最后一个参数作为整数传递,但它应该是一个指针。这个想法是你告诉recvfrom
你你的地址结构有多大,但在返回时内核告诉你它正在使用多少该结构。
我很惊讶它没有因为给出一个小整数作为指针而出错。
此外,倒数第二个参数不应该是const
.
将其更改为(此处格式化只是为了便于阅读):
socklen_t addrsize = sizeof servaddr;
receiveResult = recvfrom(socketID,
receivedMsg, sizeof *receivedMsg,
0,
(struct sockaddr *)&servaddr, &addrsize);
编辑:故事的寓意:总是打开编译器警告并理解它们,而不仅仅是让它们消失。随机转换可能会使编译器静音,但它会删除好的建议。
当你使用强制转换时,你是在告诉编译器“相信我”,如果你对编译器撒谎,它就会报复。
编辑 2:代码中的其他内容不可能是正确的。
我看不到类型toSocketID
是什么,但我看不到任何正确的结构:
fprintf(stdout, "Using port %d\n", &toSocketID.sin_port);
我想ntohs(toSocketID->sin_port)
似乎更合理。
推荐阅读
- google-cloud-platform - 使用 FDW 扩展从本地数据库到 Cloud SQL 是否可能或可行?
- android - 如何将训练有素的 scikit-learn 模型导入 android 项目
- arrays - Pandas 字节数组到十六进制转换
- javascript - javascript捕获img src“...”之间的所有内容
- java - JAVA KeyEvent 序列化错误
- macos - 具有有效签名的 macOS Kext 在第二次安装后被拒绝(高山脉)
- python - 我怎样才能摆脱循环?
- php - 遍历 wp_get_post_terms 并回显分类名称
- common-lisp - Common lisp values-list 函数
- delay - Solace messaging + delay message consumption