エンディアンネスとアドレス変換
1. バイトオーダー
1. バイトオーダーの概念
これは、マルチバイト データの格納順序と、データがメモリに格納される方法を指します。
2. 分類
ビッグ エンディアン(ネットワーク バイト オーダー): 上位ビット データは下位アドレス ビットに格納されます。 Arm アーキテクチャ、スイッチ、ルータ リトル
エンディアン(ホスト バイト オーダー): 高ビット データは上位アドレス ビットに格納されます。 x86 アーキテクチャ コンピュータ
注
LSB: 下位アドレス
MSB: 上位アドレス
3. バイトオーダー変換
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
①ホスト→to→ネットワーク
//将32位主机字节序数据转换成网络字节序数据
uint32_t htonl(uint32_t hostlong);//l代表长整型
//将16位主机字节序数据转换成网络字节序数据
uint16_t htons(uint16_t hostshort);//s代表短整型
ホストのバイトオーダーをネットワークのバイトオーダーに変換する: htons (6666); //ポート番号 6666 をネットワークのバイトオーダーに変換する
ネットワークのバイトオーダーをホストのバイトオーダーに変換する: ntohs (6666); //ポート番号 6666 をホストのバイトオーダーに変換する
2. アドレス変換
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
int inet_ntoa(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);
1、inet_pton
int inet_pton(int af, const char *src, void *dst);
機能: 32 ビットの符号なし整数データをドット付き 10 進数の IP アドレスに変換します
戻り値: 変換が成功した場合は 1 を返し、指定された IP アドレス形式が無効な場合は 0 を返し、エラーが発生した場合は -1 を返します。
パラメータの説明:
af: アドレス ファミリ。AF_INET (IPv4) または AF_INET6 (IPv6) です。
src: 変換する文字列形式の IP アドレス。
dst: 変換された IP アドレスをバイナリ形式で保存するために使用されるバッファ。
例: IP アドレス文字列を整数 IP に変換する
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char IP[] = "192.168.16.209";
int ip_int = 0;
unsigned char *p = NULL;//一定是无符号
p = (char *)&ip_int;
int ret = inet_pton(AF_INET, IP, &ip_int);
if (ret < 0) {
perror("inet_pton");
exit(-1);
}
printf("%d.%d.%d.%d\n", *p, *(p + 1), *(p + 2), *(p + 3));
return 0;
return 0;
}
2. inet_ntop (32 ビット符号なし整数データをドット付き 10 進数の IP アドレスに変換)
const char *inet_ntop(int af, const void src, char dst, socklen_t size);
機能: ドット付き 10 進 IP アドレスを 32 ビット符号なしに変換します
戻り値: 変換が成功した場合は、dst を指すアドレスを返し、指定された IP アドレス ファミリが無効な場合は、NULL を返します。
パラメータの説明:
af: アドレス ファミリ。AF_INET (IPv4) または AF_INET6 (IPv6) です。
src: 変換するバイナリ形式の IP アドレス。
dst: 変換された IP アドレスを文字列形式で保存するために使用されるバッファ。
size: dst バッファのサイズ。
場合
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
unsigned char ip_int[] = {
192,168,16,209};
char ip_str[16] = "";
inet_ntop(AF_INET, &ip_int, ip_str, sizeof(ip_str));
printf("%s\n", ip_str);
return 0;
}
3、inet_addr、inet_ntoa
IPV4のアドレス変換にのみ使用可能
in_addr_t inet_addr(const char cp);
機能: 整数データの IP アドレスをドット 10 進数の IP アドレスに変換します
戻り値: 変換が成功した場合は、変換されたバイナリ形式の IP アドレスが返されます; 指定された IP アドレスの形式が無効な場合は、INADDR_NONE (通常は -1)が返されます。
パラメータの説明:
cp: 変換する文字列形式の IP アドレス。
int inet_aton(const char cp, struct in_addr inp);
機能: 整数データをドット付き 10 進数の IP アドレスに変換します
戻り値: 変換が成功した場合は 0 以外の値が返され、指定された IP アドレス形式が無効な場合は 0 が返されます。
パラメータの説明:
cp: 変換する文字列形式の IP アドレス。
inp: 変換された IP アドレスをバイナリ形式で格納するために使用される構造体。
struct sockaddr_in {
sa_family_t sin_family; /* 地址族: AF_INET */
u_int16_t sin_port; /* 按网络字节次序的端口 */
struct in_addr sin_addr; /* internet地址 */
};
/* Internet地址. */
struct in_addr {
u_int32_t s_addr; /* 按网络字节次序的地址 */
};
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = 8080;
saddr.sin_addr.s_addr = inet_addr("192.168.16.209");
printf("ip:%s port:%d\n", inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
return 0;
}