将 ipv6 端口绑定到 ipv6 客户端套接字。但是绑定的端口与指定的不同

Bind a ipv6 port to a ipv6 client socket. But the port binded is different than the one specified

我正在尝试将 ipv6 端口绑定到 ipv6 套接字。但是绑定的端口和我指定的不一样

#include <netdb.h>
#include <netinet/tcp.h>
#include <poll.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
 #include <string.h>
#include <errno.h>
#include <stdlib.h>


int main(int argc, char *argv[]) {

    int unconnected_sock_ =
        socket(PF_INET6, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
      struct   sockaddr_in6 addr = {0};
      addr.sin6_family = AF_INET6;
      addr.sin6_port = atoi(argv[1]);
      addr.sin6_addr = in6addr_any;
      if (bind(unconnected_sock_,
                       (struct sockaddr*)(&addr),
                       sizeof(addr)) != 0) {
                           fprintf(stderr, " error : %s\n", strerror(errno));
        }
        
        
        
        struct sockaddr_in6 sin;
        socklen_t len = sizeof(sin);
        getsockname(unconnected_sock_, (struct sockaddr *)&sin, &len);
       fprintf(stderr, "port number %d\n", ntohs(sin.sin6_port)); 
   }
output:

ubun - main: ~/socket.exe 54682
port number 39637

请注意54682是0xd59a,而39637是0x9ad5。这是相同的值,但以不同的字节顺序写入。

来自man ipv6

sin6_port is the protocol port (see sin_port in ip(7));

来自man 7 ip

sin_port contains the port in network byte order. 

在打印绑定到套接字的端口的行中,将网络字节顺序转换为本地字节顺序:

fprintf(stderr, "port number %d\n", ntohs(sin.sin6_port));

在设置请求端口号的行中,您没有将字节顺序从本机顺序转换为网络顺序:

addr.sin6_port = atoi(argv[1]);

要获得预期的行为,您应该将其修改为:

addr.sin6_port = htons(atoi(argv[1]));