Linux网络编程基础API
- socket地址API
- 主机字节序和网络字节序
- 创建socket
- 命名socket
- 监听socket
- 接收连接
- 发起连接
- 关闭连接
- 数据读写
- 带外标记
- 地址信息函数
- socket选项
- 网络信息API
socket地址API
主机字节序和网络字节序
在 Linux 系统中,主机字节序(Host Byte Order)和网络字节序(Network Byte Order)是两个重要的概念。
- 主机字节序是指 CPU 直接处理数据时使用的字节序。在 x86 架构的 Linux 系统中,主机字节序通常是小端字节序(Little Endian),即最低有效字节(Least Significant Byte)位于最低内存地址。
- 网络字节序是指在网络通信中使用的字节序。在 TCP/IP 协议中,网络字节序通常是大端字节序(Big Endian),即最高有效字节(Most Significant Byte)位于最低内存地址。
在进行网络编程时,经常需要在主机字节序和网络字节序之间进行转换。例如,在发送数据时,需要将主机字节序转换为网络字节序;在接收数据时,需要将网络字节序转换为主机字节序。
在 Linux 系统中,可以使用htonl()、htons()、ntohl()和ntohs()等函数进行字节序转换。这些函数的命名规则如下:
h表示主机(Host)。n表示网络(Network)。l表示长整型(Long)。s表示短整型(Short)。
例如,htonl()函数将一个 32 位的整数从主机字节序转换为网络字节序,ntohl()函数将一个 32 位的整数从网络字节序转换为主机字节序。
下面是一个简单的示例,展示了如何在 Linux 中进行字节序转换:
#include <iostream>
#include <arpa/inet.h>
int main() {
// 定义一个32位整数
uint32_t host = 0x12345678;
// 将主机字节序转换为网络字节序
uint32_t network = htonl(host);
// 将网络字节序转换为主机字节序
uint32_t host2 = ntohl(network);
// 打印结果
std::cout << "主机字节序:" << std::hex << host << std::endl;
std::cout << "网络字节序:" << std::hex << network << std::endl;
std::cout << "转换后的主机字节序:" << std::hex << host2 << std::endl;
return 0;
}
在上面的示例中,我们定义了一个 32 位的整数host整数,然后使用htonl()函数将其转换为网络字节序,并使用ntohl()函数将其转换回主机字节序。最后,我们打印出转换前后的结果。
判断机器字节序
#include <iostream>
#include <endian.h>
// 判断机器字节序函数
bool isLittleEndian() {
return __BYTE_ORDER__ == LITTLE_ENDIAN;
}
void isLittleEndian02() {
union {
short value;
char union_bytes[sizeof(short)];
} test;
test.value = 0x0102;
if (test.union_bytes[0] == 1 && test.union_bytes[1] == 2) {
std::cout << "这台机器是大端字节序(big endian)" << std::endl;
} else if (test.union_bytes[0] == 2 && test.union_bytes[1] == 1) {
std::cout << "这台机器是小端字节序(little endian)" << std::endl;
} else {
std::cout << "unknown..." << std::endl;
}
}
int main() {
if (isLittleEndian()) {
std::cout << "这台机器是小端字节序(little endian)" << std::endl;
} else {
std::cout << "这台机器是大端字节序(big endian)" << std::endl;
}
isLittleEndian02();
return 0;
}
/*
这台机器是小端字节序(little endian)
这台机器是小端字节序(little endian)
*/
函数isLittleEndian(),它使用__BYTE_ORDER__和__LITTLE_ENDIAN__宏来判断机器的字节序。如果__BYTE_ORDER__等于__LITTLE_ENDIAN__,则说明机器是小端字节序;否则,机器是大端字节序。
函数isLittleEndian02(),在这个代码中,使用了一个union(联合体)来同时访问一个 16 位整数的不同字节。在这个union中,value成员是一个 16 位整数,而union_bytes成员是一个字符数组,长度为sizeof(short),即 2。
首先,将 0x0102 赋值给value成员。然后,检查union_bytes成员中的第一个和第二个字节的值。如果第一个字节的值为 1,第二个字节的值为 2,那么这台机器是大端字节序;如果第一个字节的值为 2,第二个字节的值为 1,那么这台机器是小端字节序;否则,字节序是未知的。