一. TCP/IP协议
协议即: 通信双方必须遵循的规则, 由ISO规定, RFC 文档。
1. OSI 七层模型 与 TCP/IP 四层模型
2. TCP/IP 协议族的成员们
- 应用层(http 超文本传输协议 ftp 文件传输协议, telnet 远程登录协议, ssh 安全外壳协议, smtp 简单邮件发送协议, pop3 接收邮件协议)
- 传输层 (tcp 传输控制协议, udp 用户数据包协议)
- 网络层 (ip 网络互联协议, icmp 网络控制消息协议, igmp 网络组管理协议)
- 网络接口层(arp 地址转换协议, rarp 反向地址转换协议, mpls 多协议标签交换)
每一层负责的工作:
- 网络接口层: 负责将二进制流转换为数据帧,并进行数据帧的发送和接收, 数据帧是独立的网络信息传输单元。
- 网络层:负责将数据帧封装层IP数据报,并运行必要的路由算法。负责点到点的传输(主机或路由器)。
- 传输层: 负责端对端之间的通信会话连接和建立,传输协议的选择根据数据传输的方式而定,负责端到端的传输(源主机与目的主机)
- 应用层: 负责应用程序的网络访问,通过端口号来识别各个不同的进程。
3. ip协议与路由器
其中网络层的 ip 协议是构成 Internet 的基础, 互联网的主机通过IP地址来表示,且互联网上有大量路由器
负责根据IP地址选择合适的路径转发数据包。
路由器是在工作在网络层的网络设备,同时兼有交换机的功能,可以在不同的链路层接口之间转发数据包。
IP 协议不保证数据传输的可靠性,数据包在传输过程中可能丢失, 可靠性可用在上层协议或应用程序中提供支持。
4.每一层相关协议的注解
“IP地址和MAC地址相同点是它们都唯一,不同的特点主要有: 对于网络上的某一设备,如一台计算机或一台路由器,其IP地址是基于网络拓扑设计出的,同一台设备或计算机上,改动IP地址是很容易的(但必须唯一),而MAC则是生产厂商烧录好的,一般不能改动。
-
ARP: (地址转换协议)用于获得同一物理网络中的硬件主机地址(MAC),是设备通过知道的IP地址获得主机不知道的物理地址的协议。
-
RARP: (反向地址转换协议)允许局域网的物理机器从网关服务器的 ARP表或缓存上请求其IP地址。
-
IP :(网际互联协议)负责在主机和网络之间寻址和路由转发数据包。
-
ICMP:(网络控制消息协议)用于发送报告有关数据包的传送错误的协议。
-
IGMP:(网络组管理协议)被 IP 主机用来向本地多路广播路由器报告主机组成员的的协议,主机与本地路由器之间使用 Internet
组管理协议来进行组播组成员信息的交互。 -
TCP:(传输控制协议)为用户提供可靠的通信连接。 适合于一次传输大批数据的情况,并适用于要求得到响应的应用程序。
-
UDP: (用户数据包协议)提供了无连接通信,且不对传送包进行可靠的保证,适用于一次传输少量数据。
二. 网络相关概念
1. socket 概念
Linux 中的网络编程是通过 socket 接口来进行的。
特点:
- socket 是一种特殊的I/O接口,也是一种文件描述符
- socket 是常用的进程间通信机制(同机器或非同机器之间均可)
组成:
- 每一个socket 都用一个半相关描述{ 协议, 本地地址,本地端口} 表示,完整的套接字使用一个 相关描述{协议,本地地址,本地端口, 目的地址,目的端口} 表示
- socket 类似于文件的函数调用,使用其返回一个socket描述符,随后的连接建立,数据传输等操作均通过 socket来实现。
2. socket 类型
(1) 流式 socket(SOCKET_STREAM) -> 用于 TCP 通信
(2) 数据报 socket(SOCKET_DGRAM) -> 用于 UDP通信
(3) 原始 socket(SOCKET_RAW)-> 用于新的网络协议实现的测试等
原始套接字允许对底层协议如IP和ICMP进行直接访问,功能强大但使用不便,主要用于一些协议的开发。
3. socket 信息数据结构
#include <netinet/in.h>
struct sockaddr {
unsigned short sa_family; //地址族
char sa_data[14]; //14字节的协议地址包含其socket的IP地址于端口号
};
struct sockaddr_in {
//在sockaddr上进行了划分,使得端口,ip分开(常用)
short int sin_family;
unsigned short int sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8]; //填充的字节,与sockaddr保持一样大小
};
struct in_addr {
in_addr_t s_addr; //32位ipv4地址,网络字节序
}
sin_family: AF_INET-> IPV4 协议 AF_INET6 -> IPV6协议
4.数据存储优先顺序的转换
在计算机数据存储有两种字节优先顺序:高位字节优先(大端模式)和低位字节优先
- 内存的低地址存储数据的低字节,高地址存放数据的高字节的方式叫小端模式。
- 内存的高地址存储数据的低字节,低地址存放数据的高字节的方式叫大端模式
例如: 10 在 内存中存放的是 0x00000000a;
大端模式即: 0x00000000a
小端模式即: 0x0a0000000
可以用 char* 取一个int类型的变量的地址(用10),得到如果解引用后是10,那么是小端,是0则是大端
因为指针总是取一个变量的低地址开始(栈的地址是向下增长)
但是呢,在网络中的端口号和IP地址都是以网络字节序(大端法),因此我们需要对这两个变量的字节存储优先顺序进行相互转化。
这里用到4个函数:
#include <netinet/in.h>
uint16_t htons(unit16_t host16bit); 从host16位比特转换位 network 的short类型(用于端口转换)
uint16_t ntohs(unit16_t net16bit); 反转
unit32_t htonl(unit32_t host32bit); 从host32位比特转换为 network的long 类型(用于ip转换)
unit32_t ntohl(unit32_t net32bit); 反转
成功:返回转换的字节序
失败:返回-1
5. 地址格式转换
我们在表达地址时经常采用的是点分十进制表示的数值,而socket 编程中使用的是32位的网络字节序的二进制值