OSI/RM结构与TCP/IP模型
网络协议是为网络数据交换而制定的规则、约定、标准, 一个功能完备的计算机网络需要制定一整套复杂的协议集,网络协议是按层次结构来组织的,网络层次结构模型与各层协议的集合称为网络体系结构。
OSI/RM结构七层:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
TCP/IP模型四层:
物理层:负责通信网络收发数据包
网络层:选择、流量控制、与网络拥塞问题,IP协议是该层核心。
传输层:机器之间建立用于会话的端到端连接(用于数据的传输),该层的核心协议是TCP、UDP协议。
应用层:主要为用户提供针对性的服务,该层代表性的协议有:HTTP、SMTP、FTP、TELNET。
1、建立连接时的三次握手
2、断开连接时的四次挥手
MAC地址、IP地址、域名
MAC地址
也叫物理地址,每张网卡在生产时厂家就是固化一个48位的地址(6个字节,通常表示为12个16进制数,如:00-16-EA-AE-3C-40),此地址全世界唯一,交换机路由器以此来确认网络设备位置的位址,缺点是不方便记忆,不够灵活。
IP地址
IP 地址是基于逻辑的,比较灵活,不受硬件的限制,也容易记忆,方便划分子网,因此在计算机网络中表面上使用IP进行通信,目前由4个不超过255的整数组成,一般用点分十进制表示(192.168.2.180)。而在交换机、路由器中有张ARP表,一列记录MAC,另一列记录IP地址,通过ARP协议的RARP协议可以对IP地址和MAC地址进行转换。
域名
由于普通人很难记忆大量IP地址,便有了代替IP地址的文字,但需要最终翻译成IP地址才能通信,提供翻译服务的计算机叫DNS服务器,需要在政府部分备案才能加入DNS服务器。
ip地址的分类:
A类:第一个二进制位必须是0
0.0.0.0~127.255.255.255
B类:前两位的二进制位必须是10
128.0.0.0~191.255.255.255
C类:前三位的二进制位必须是110
192.0.0.0~223.255.255.255
D类:前四位的二进制位必须是1110
224.0.0.0~239.255.255.255
E类:前四位的二进制位必须是1111
240.0.0.0~255.255.255.255
公有IP和私有IP
公有ip:在网络服务提供商登记过的ip地址叫公有ip
私有ip:由一此公司或组织自己分配的,不能在网络公开直接访问的ip。
网络通信的基本概念
1.TCP协议
TCP (Transmission Control Protocol, 传输控制协议) 面向连接的服务,相当于打电话。
2.UDP协议
UDP (User Datagram Protocol, 用户数据报文协议) 面向无连接的服务,相当于发短信。
UDP | TCP | |
---|---|---|
是否连接 | 无连接 | 面向连接 |
是否可靠 | 不可靠传输,不使用流量控制和拥塞控制 | 可靠传输,使用流量控制和拥塞控制 |
连接对象个数 | 支持一对一,一对多,多对一和多对多交互通信 | 只能是一对一通信 |
传输方式 | 面向报文 | 面向字节流 |
首部开销 | 首部开销小,仅8字节 | 首部最小20字节,最大60字节 |
使用场景 | 适用于实时应用(IP电话、视屏会议、直播等) | 适用于要求可靠传输的应用,如文件传输 |
socket
套接字,是一种接口技术,它封装了TCP/IP通信协议,使用它可以让计算机之间通过网络传输数据,所有的操作系统使用的都基于socket的接口进行网络通信的。
不光可以用于网络间通信,还可以用于进程间通信,或者可以将网络通信理解为不同计算之间的进程间通信
其实是一种内核对象,以描述符的形式呈现,发送数据即写文件,接收数据读文件。
int socket(int domain, int type, int protocol);
功能:创建一个socket对象
domain:地址域,什么类型的地址
AF_UNIX, AF_LOCAL 接收下将使用路径地址进行进程间通信
AF_INET 使用ipv4地址进行网络通信
AF_INET6 使用ipv6地址进行网络通信
type:
SOCK_STREAM 使用数据流进行通信 TCP
SOCK_DGRAM 使用数据报通信 UDP
protocol:特殊的通信协议,一般不用,写0即可。
返回值:成功返回socket描述符,失败返回-1。
通信地址
// 基本地址
struct sockaddr{
sa_family_t sa_family; // 地址域
char sa_data[14];
}
struct sockaddr_un{
sa_family_t sun_family; // 地址域 与domain一致即可
char sun_path[108]; // socket文件的路径
}
// 网络类型地址
struct sockaddr_in{
sa_family_t sin_family; // 地址域 与domain一致即可
int_port_t sin_port; // 端口号,注意要的是大端数据,2字节
struct in_addr sin_addr;// ip地址
}
// ip地址
struct in_addr{
in_addr_t s_addr; // ip地址的整数,注意要的是大端数据,4字节
}
地址字节序转换成网络字节序
uint32_t htonl(uint32_t hostlong);
功能:把本地字节序的4字节整数转换成网络字节序
uint16_t htons(uint16_t hostshort);
功能:把本地字节序的2字节整数转换成网络字节序
uint32_t ntohl(uint32_t netlong);
功能:把网络字节序的4字节整数转换成本地字节序
uint16_t ntohs(uint16_t netshort);
功能:把网络字节序的2字节整数转换成本地字节序
ip地址转换:
in_addr_t inet_addr(const char *cp);
功能:把点分十进制的ip地址字符串转换成网络字节序的4字节整数
char *inet_ntoa(struct in_addr in);
功能:把以4字节整数形式的ip地址转换成点分十进制的ip地址字符串
基于TCP的编程模型
服务端(等待连接的) | 客户端(发起连接的) | 用到的函数 |
---|---|---|
创建socket对象 | 创建socket对象 | socket |
准备地址(自己) | 准备地址(服务端) | sockaddr_in |
地址与socket绑定 | … | bind |
监听并设置排队的数量 | … | listen |
等待连接 | 链接服务端 | accept/connect |
创建线程或进程给服务客户端 | … | fork/pthread_create |
收发数据 | 收发数据 | read/write |
关闭 | 关闭 | close |
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:绑定地址域与socket对象。
sockfd:socket对象描述符。
addr:地址结构体指针,实际参数应该是 struct sockaddr_un* 或者 struct sockaddr_in* 因此需要强制类型转换。
addrlen:地址结构体的字节数,以此区分是什么类型地址。
返回值:成功返回0,失败返回-1。
int listen(int sockfd, int backlog);
sockfd:socket对象描述符。
backlog:待排队的数量。
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:用于接收连接的客户端。
sockfd:socket对象描述符。
addr:存储客户端的地址,实际参数应该是 struct sockaddr_un* 或者 struct sockaddr_in* 因此需要强制类型转换。
addrlen:既是输入也是输出。
输入:使用的是什么类型的地址结构体接收的。
输出:实际接收到的地址结构体类型。
返回值:成功返回与客户端建立连接的socket对象描述符,凭此收发数据,失败返回-1。