ISO/OSI参考模型
- 应用层(Application Layer)
- 表示层(Presentation Layer)
- 会话层(Session Layer)
- 传输层(Transport Layer)
- 网络层(Internet Layer)
- 数据链路层( Data Link Layer)
- 物理层(Physical Layer)
TCP/IP四层模型
- 应用层(Application Layer)–合并了上面的1,2,3三层
- 传输层(Transport Layer)
- 网络层(Internet Layer)
- 链路层 (LinkLayer) ———–合并了上面的6,7两层
端口
- 众所周知的端口( Well Known Ports):0~1023
- 注册端口(Registered Ports):1024~49151
- 动态或私有端口(Dynamic or Private Ports):49152~65535
MTU
- 以太网和IEEE802.3对数据帧的长度都有限制,其最大值分别为1500和1492字节,将这个限制称作最大传输单元(MTU,Maximum Transmission Unit)
- 如果IP层有一个数据报要传,而且数据的长度比链路层的MTU还大,那么IP层就要进行分片(Fragmentation),将数据报分成若干片,这样每一片都小于MTU。
- 当网络上的两台主机互相进行通信时,两台主机之间要经过多个网络,每个网络的链路层可能有不同的MTU,其中两台通信主机路径中的最小MTU被称作路径MTU。
判断网络字节序
大端
小端
网络字节序转换函数
1.uint32_t htonl(uint32_t hostlong);
2.uint32_t htons(uint32_t hostshort);
3.uint32_t ntohl(uint32_t netlong);
4.uint32_t ntohs(uint16_t netshort);
说明
在上述函数中,h代表host,n代表network,s代表short,l代表long 使用代码
#include <stdio.h>
int main(int argc, const char *argv[])
{
unsigned int x = 0x12345678;
unsigned char* p = (unsigned char*)&x;
printf("%0x %0x %0x %0x\n", p[0], p[1], p[2], p[3]);
unsigned int y = htonl(x);
p = (unsigned char*)&y;
printf("%0x %0x %0x %0x\n", p[0], p[1], p[2], p[3]);
return 0;
}
结果:
78 56 34 12 ——小端
12 34 56 78 ——大端(网络字节序)
地址转换函数
地址转换函数
头文件
#include <netinet/in.h>
#include <arpa/inet.h>
函数
int inet_aton(const char* cp, struct in_addr* inp);
in_addr_t inet_addr(const char* cp);
char* inet_ntoa(struct in_addr in);
使用样例
#include <stdio.h>
#include <arpa/inet.h>
int main(int argc, const char *argv[])
{
// 点分十进制转换成网络字节序
unsigned long addr = inet_addr("192.168.0.100");
// 网络字节序转换成主机字节序
printf("addr=%u\n", ntohl(addr));
struct in_addr ipaddr;
ipaddr.s_addr = addr;
printf("%s\n", inet_ntoa(ipaddr));
return 0;
}
结果
addr=3232235620 192.168.0.100
- 流式套接字 SOCK_STREAM
- 提供面向连接的、可靠的数据传输服务,数据无差错,无重复的发送,且按发送顺序接收。
- 数据报式套接字 SOCK_DGRAM
- 提供了无连接服务。不提供无错保证,数据可能丢失或重复,并且接收顺序混乱。
- 原始套接字 SOCK_RAW