htons函数用于将 16 位无符号短整型数值从主机字节序转换为网络字节序(大端序)。以下是 Delphi 的实现:
function htons(hostshort: Word): Word;
begin
{$IFDEF ENDIAN_LITTLE}
// 在小端序系统上需要转换字节顺序
Result := ((hostshort and $00FF) shl 8) or
((hostshort and $FF00) shr 8);
{$ELSE}
// 在大端序系统上不需要转换
Result := hostshort;
{$ENDIF}
end;
使用示例
procedure TForm1.Button1Click(Sender: TObject);
var
hostPort, networkPort: Word;
begin
hostPort := 12345; // 0x3039
networkPort := htons(hostPort);
ShowMessage(Format('主机序端口: %d (0x%.4x), 网络序端口: %d (0x%.4x)',
[hostPort, hostPort, networkPort, networkPort]));
end;
功能说明
-
检测系统字节序(通过
ENDIAN_LITTLE定义) -
在小端序系统上,将 16 位数值的高低位字节交换
-
在大端序系统上,直接返回原值(因为网络字节序就是大端序)
相关函数
// 网络序转主机序的对应函数
function ntohs(netshort: Word): Word;
begin
Result := htons(netshort); // 实现相同
end;
实际应用
在网络编程中,htons通常用于端口号的转换:
// 设置 socket 地址结构时的典型用法
var
Addr: TSockAddrIn;
begin
Addr.sin_family := AF_INET;
Addr.sin_port := htons(80); // HTTP 端口
// ...
end;
注意事项
-
Delphi 中
Word是 16 位无符号整数类型,对应 C 语言的uint16_t -
如果使用 Indy 网络库,可以直接使用
IdGlobal单元中的GStack.HostToNetwork和GStack.NetworkToHost函数 -
现代 Delphi 版本(XE2+)在
System.Net单元中也提供了类似的字节序转换函数
关于字节序和大端序系统的解释
字节序基本概念
字节序(Endianness)是指多字节数据在内存中的存储顺序,主要分为两种:
-
大端序(Big-endian):高位字节存储在低地址
-
小端序(Little-endian):低位字节存储在低地址
Windows 系统的字节序
Windows 系统属于小端序系统(几乎所有 x86/x64 架构的处理器都是小端序)。
因此,在 Windows 系统上:
-
htons和htonl函数需要进行字节序转换 -
从网络接收的数据(大端序)需要转换为小端序才能正确使用
-
发送到网络的数据需要从小端序转换为大端序
为什么大端序系统不需要转换
网络协议(如 TCP/IP)规定使用大端序作为标准字节序(因此称为"网络字节序")。
所以:
-
在大端序系统上,主机字节序与网络字节序相同,不需要转换
-
在小端序系统上,必须进行字节序转换
实际例子
以数字 0x1234(16位)为例:
|
系统类型 |
内存表示(低地址 → 高地址) |
|---|---|
|
大端序系统 |
|
|
小端序系统 |
|
网络传输总是使用大端序表示:12 34
Delphi 中的实现细节
{$IFDEF ENDIAN_LITTLE}
// 小端序系统需要转换
{$ELSE}
// 大端序系统不需要转换
{$ENDIF}
虽然 Windows 是小端序,但 Delphi 的跨平台编译系统可以自动处理不同平台的字节序问题。
常见的大端序系统
虽然很少见,但确实存在大端序系统:
-
某些 PowerPC 架构的系统
-
某些 ARM 系统(可配置为大端序)
-
早期的 Macintosh(PowerPC 时代)
-
某些嵌入式系统
但在实际开发中,除非您明确知道目标平台是大端序,否则应该总是使用 htons/htonl函数来确保代码的可移植性。

5422

被折叠的 条评论
为什么被折叠?



