绑定套接字时为什么要将端口号转换为网络字节顺序?

时间:2014-03-22 05:39:18

标签: c sockets

我遇到了这段代码,这些代码出现在设置套接字的内容中:

#define PORT xxxx

struct sockaddr_in self;
self.sin_family = PF_INET;
self.sin_port = htons(PORT);

我知道我们需要将通过网络传输的数据的字节顺序转换为Network Byte Order,但我不知道为什么我们需要在设置时将端口号转换为一个插座。我的意思是,当我们结束时,它不是一个本地的"事情?假设我们打算绑定的端口是1,机器实际上使用小端;既然我们将它转​​换为网络字节顺序,我们是不是要将一个完全不同的端口绑定到套接字?

5 个答案:

答案 0 :(得分:3)

我想我们假设你正在使用TCP。端口号将位于数据包标头中。这将被传播。所以它将在网络字节顺序中。

答案 1 :(得分:1)

您是在问为什么应用程序程序员而不是库在内部执行吗?如果是这样,我能想到的唯一技术优势是它允许应用程序执行一次转换并缓存并使用多次,而无需进行多次转换。

在TCP上,每个连接只需要使用一次,通常不会建立数百万个连接。但是在UDP上,您每次发送数据包时都会使用它,因此可以合理地假设您将进行数百万或数十亿次此类调用。

然后,对于无数次呼叫说sendto()的UDP或您有什么要求,如果需要的话,重新排序的地址将提供给OS,该OS可以将其原样直接复制到传出网络数据包中。

在内核中执行此操作的另一种方法是,每次调用sendto()时,都要一遍又一遍地获取应用程序所知道的相同地址,并每次都将其重新转换。

由于sendto()受益于此,这也许是他们使其余API以相同方式工作的充分理由。

答案 2 :(得分:0)

您通过网络传输端口号。它是TCP的IP数据包的一部分。查找RFC(ietf.org/rfc/rfc793.txt)

答案 3 :(得分:0)

struct sockaddr_in只是struct sockaddr的包装结构:

struct sockaddr {
    unsigned short sa_family;
    char           sa_data[14];
};

此处将端口号和IP地址保持在一起。它们在sa_data[14]中保持在一起 - 第一个2 bytes持有端口号,下一个4 bytes持有IP地址。剩余的8 bytes未使用。当您使用8 bytes时,这些sin_zero[8]会通过sockaddr_in清除为零。

这完全是通过网络发送的,包括网络顺序的端口号。

答案 4 :(得分:0)

机器可以使用小/大尾数的不同编码。为了标准化,在通过网络进行通信时应使用统一的编码。因此,无论字节序大小如何,都必须将其转换为网络字节顺序。重要的是,它是统一的,并且网络中的每个设备和软件都可以正确理解。