我正在尝试使用unix套接字来测试向localhost发送一些udp数据包。
据我所知,在设置ip地址和端口以发送数据包时,我会将sockaddr_in
填充为转换为网络字节顺序的值。
我在OSX上,我对这个
printf("ntohl: %d\n", ntohl(4711));
printf("htonl: %d\n", htonl(4711));
printf("plain: %d\n", 4711);
打印
ntohl: 1729232896
htonl: 1729232896
plain: 4711
因此,两个函数都没有实际返回普通值。我希望看到结果不同,因为x86是little-endian(afaik),或者与实际数字4711相同且相同。显然我不明白htonl
和ntohl
和他们的变种做。我错过了什么?
相关代码如下:
int main(int argc, char *argv[])
{
if (argc != 4)
{
fprintf(stderr, "%s\n", HELP);
exit(-1);
}
in_addr_t rec_addr = inet_addr(argv[1]); // first arg is '127.0.0.1'
in_port_t rec_port = atoi(argv[2]); // second arg is port number
printf("Address is %s\nPort is %d\n", argv[1], rec_port);
char* inpath = argv[3];
char* file_buf;
unsigned long file_size = readFile(inpath, &file_buf); // I am trying to send a file
if (file_size > 0)
{
struct sockaddr_in dest;
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = rec_addr; // here I would use htons
dest.sin_port = rec_port;
printf("ntohs: %d\n", ntohl(4711));
printf("htons: %d\n", htonl(4711));
printf("plain: %d\n", 4711);
int socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (socket_fd != -1)
{
int error;
error = sendto(socket_fd, file_buf, file_size + 1, 0, (struct sockaddr*)&dest, sizeof(dest));
if (error == -1)
fprintf(stderr, "%s\n", strerror(errno));
else printf("Sent %d bytes.\n", error);
}
}
free(file_buf);
return 0;
}
答案 0 :(得分:7)
正如其他人所提到的,htons
和ntohs
都反转了little-endian机器上的字节顺序,并且在big-endian机器上都是no-ops。
未提及的是这些函数采用16位值并返回16位值。如果要转换32位值,则需要使用htonl
和ntohl
。
这些函数的名称来自某些数据类型的传统大小。 s
代表short
而l
代表long
。 short
通常为16位,而旧系统long
为32位。
在您的代码中,您无需在htonl
上调用rec_addr
,因为该值由inet_addr
返回,并且该函数以网络字节顺序返回地址。 / p>
但您需要在htons
上致电rec_port
。
答案 1 :(得分:5)
两个函数都反转了字节的顺序。为什么会返回论证本身?
尝试htons(ntohs(4711))
和ntohs(htons(4711))
。
答案 2 :(得分:4)
"网络字节顺序"总是意味着大端。
"主机字节顺序"取决于主机的架构。根据CPU,主机字节顺序可能是小端,大端或其他。 (g)libc适应主机架构。
由于英特尔架构是小端,这意味着两个函数都在相同:颠倒字节顺序。
答案 3 :(得分:2)
这些功能名称不佳。 Host to network
和network to host
实际上是同一个东西,如果这是一个小端机器,它应该被称为'更改字节序'
所以在你做的小端机器上
net, ie be, number = htonl / ntohl (le number)
并在线上发送号码。当你从电线上得到一个大端数字时
le num = htonl/ntohl (net ,ie be, number)
在一台大型机器上
net, ie be, number = htonl / ntohl (be number)
和
be num = htonl/ntohl (net ,ie be, number)
在最后一种情况下,您会看到这些功能无效