C UDP套接字连接没有正确分配端口

C UDP socket connection isn't assigning the ports right way

我有以下架构:

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);

在发送之前我做了:

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 你的地址结构有多大,但是在 return 上内核告诉你它使用了多少该结构。

我很惊讶它没有因为给出一个小整数作为指针而出错。

另外,倒数第二个参数不应该是const

将其更改为(此处格式化只是为了便于阅读):

socklen_t addrsize = sizeof servaddr;

receiveResult = recvfrom(socketID,
                        receivedMsg, sizeof *receivedMsg,
                        0,
                        (struct sockaddr *)&servaddr, &addrsize);

编辑:故事的寓意:始终打开编译器警告并理解它们,而不是让它们消失。随机转换可能会使编译器静音,但会删除好的建议。

当你使用强制转换时,你是在告诉编译器 "trust me",如果你对编译器撒谎,它会报复的。

编辑 2:代码中的其他内容不正确。

我看不到 toSocketID 的类型,但我看不到任何正确的构造:

fprintf(stdout, "Using port %d\n", &toSocketID.sin_port);

我认为 ntohs(toSocketID->sin_port) 似乎更合理。