IP地址和端口号
在IP数据报头中,有两个IP地址,分别是IP地址和目的IP地址;
端口号是传输层协议中的内容;
- 是一个2字节16位的整数;
- 用来标识进程,让当前的操作系统知道数据应该交给哪一个进程进行处理;
- IP地址+端口号就可以标识网络上的某一台主机的某一个进程;
- 一个端口号只能被一个进程进行占用,但一个进程可以绑定多个端口号;
之前在我们学习C语言时,我们知道内存中的数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分,网络数据流向同样也有大端小端之分,那么怎样去定义网络数据流的地址呢?我们先来了解以下几个概念:
小端:地位低地址;
大端:高位高地址:
字节序:CPU对内存的访问顺序;
主机字节序:指的是机器本身的字节序,如果是大端,则主机字节序就是大端;如果是小端,主机字节序就是小端;
网络字节序:规定网络中传输的字节序使用大端;如果是小端机器在传输数据的时候,需要将数据转化为大端字节序进行传输,对端机器默认传输过来的数据是大端字节序的。
通常字节序和计算机的架构有关系,我们常见的X_86
体系结构的是小端。
我们如何让验证自己的机器是大端机器还是小端机器?
#include <stdio.h>
int main()
{
union Data
{
int a;
char b;
}data;
data.a = 1;
if(data.b == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
验证得出机器是小端
小结:
大端机器和小端机器进行传输:
- 不论是网络报头部分的IP或者port,还有要传输的是源数据,都是需要进行转化成为网络字节序来进行传输的;
小端机器和小端机器进行传输:
- 当通信双方都是小端机器的时候,对于网络报头当中的ip和port还是必须遵守网络字节序的格式进行传输,否则网络链路上面的转发设备就无法正确的转发该条数据(因为是按照大端进行读取的);
- 如果双方都是小端机器,我们传输的数据可以不用进行字节序的转换;
当前95%的机器都是小端机器;
主机字节序和网络字节序之间的转换
为了使网络程序拥有可移植性,使同样的代码在大小端机器上都可以成功编译运行,我们采用调用下面的库函数进行网络字节序和主机字节序之间的转换;
主机字节序——>网络字节序(IP和端口号两方面)
#include <arpa/inet.h>
uint 32_t htonl(uint 32_t host long);
uint 16_t htons(uint 16_t host short);
网络字节序——>主机字节序
uint 32_t ntohl(uint 32_t host netlong);
uint 16_t ntohs(uint 16_t host netshort);
- h表示host,n表示network,l表示32位长整数,s表示16位短整数;
- 如果主机是大端字节序,这些函数将不做转换,将参数返回;
- 如果主机是小端字节序,这些函数的参数将参数进行相对应的转换然后进行返回;