一、计算机网络
什么是计算机网络
计算机网络是指地理位置不同的具有独立功能的多台计算机以及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
计算机网络的功能
- 数据通信
- 资源共享
- 提高系统的可靠性
- 分布式网络处理和负载均衡
计算机网络的组成
- 通信子网:网卡、线缆、集线器、中继器、交换机、路由器
- 资源子网:网络中的计算机、打印机、电话等一些可以提供服务的设备。
- 计算机网络软件:
- 协议软件:规定了计算机通信的规则,TCP/IP协议族
- 网络通信软件:网络中实现计算机与设备之间通信的软件(网卡驱动)
- 网络管理软件:防火墙,SELinux
- 网络应用软件:浏览器、迅雷
- 网络操作系统:可以提供网络服务的计算机操作系统,Windows server2008、UNIX、LINUX
- 计算机网络的分类:
- 按照网络作用范围划分:局域网、域域网、广域网
- 按网络技术划分:广播式网络、点到点网络
- 按传输介质划分:有线网、无线网、微波通信、卫星通信
- 计算机网络拓扑结构:星型、树型、总线型、环型、网状型
- 计算机网络的发展过程:
- 以计算机为中心的联系系统
- 分组交换网络的诞生
- 网络体系结构与协议标准化
- 20世纪80年代ISO组织提出开放式系统互联参考模型(OSI参考模型)
- 但由于这个模型照顾了各方的利益,所以太过于庞大,因此至今都没有成熟的产品,目前我们所使用时一系列协议的集合,简称TCP/IP簇,通常也叫做TCP/IP模型
- 目前所有的计算机系统都按照这份协议进行通信,所有不同的操作系统之间才可能进行网络通信。
- C/C++/Java/python -> Windows -> socket -> TCP/IP <-> TCP/IP ->socket -> Linux ->C/C++/Java/python
- 高速计算机网络(5G)
- 网卡:它负责将数据发送到网络上,也负责从网络中获取数据,每个网卡上都有一个独一无二的MAC地址
- OSI参考模型与TCP/IP参考模型:
- 网络协议是为网络数据交换而定制的规则、约束、标准,一个功能完备的计算机网络需要制定一套复杂和协议集,目前的网络协议是按层次结构组织的,网络层次结构模型与各层协议的集合称为网络体系结构。
- OSI从上到下一共七层:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
- TCP/IP目前只实现了四层,从上到下:
- 物理层:负责通信网络收发数据包
- 网络层:选择、流量控制、网络堵塞、IP协议是该层的核心
- 传输层:机器之间建立用于会话端到端连接(用于数据传输),核心:TCP/UDP
- 应用层:主要为用户提供针对性的服务,这一层代表协议有:HTTP,SMTP,FTP,SNMP,TELENT
OSI | TCP |
---|---|
物理层 数据链路径 | 物理层 |
网络层 | 网络层 |
传输层 | 传输层 |
会话层 表示层 应用层 | 应用层 |
- IP地址ipv4
在计算机网络中每一台计算机都必须有一个唯一的标识(MAC地址不容易记忆),它就是IP地址,目前在计算机以.分十进制表示(4个不超过255的整数),但在程序中它就是4字节的整数。- 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:由一些公司或组织自己分配的,不能在网络中公开直接访问的。
- 子网掩码:
- 由4个不超过255的整数,.分十进制表示。
- 网络地址=ip地址 按位& 子网掩码
- 只有在同一子网内的IP地址才可能直接进行通信,否则必须经过路由器。
- 网关地址:负责子网出口的计算机,一般由路由器担任(路由器就是一台且有路由功能的计算机)。
- 端口号
- ip地址能决定我们与哪一台计算机通信,而端口号决定了我们与计算机上的哪个进程通信。
- 1~1024基本上已经操作系统预定完了,因此我们在编程时一般要使用1024以上的。
- http:80 ftp:21 ssh:22 telnet:23
二、网络通信的基本概念
-
TCP和UDP的区别
- TCP:传输控制协议,面向连接的服务(打电话),安全、可靠(三次握手、响应+重传、四次挥手),速度相对较慢,一般应用在对安全性、完整性有严格要求的场景:FTP、SMTP、HTTP。
-
三次握手:
- A要知道,A能到B,B也能到A。
- B要也要知道,A能到B,B也能到A。
- A 你听的到吗-> B (此时可知:B知道了A能到B)
- B 我能听到,你呢-> A(此时可知:A知道了A能到B且B能到A)
- A 我也能听到-> B (此时可知:B知道了B也能到A)
-
四手挥手:
- 目的是保证关闭前发送完所有数据包(应用层已经交给底层了,位底还没有完全发送出去)。
- A 发送关闭请求-> B
- A <-发送请求响应 B (B检查是否有末发送完成的数据)
- A <-可以关闭 B
- A 发送关闭消息-> B
-
- UDP:用户数据报文协议,面向无连接的服务(发短信),不保证安全、可靠,但大多数情况下是可靠的,相对较快,流媒体(在线的视频、音频)。
- TCP:传输控制协议,面向连接的服务(打电话),安全、可靠(三次握手、响应+重传、四次挥手),速度相对较慢,一般应用在对安全性、完整性有严格要求的场景:FTP、SMTP、HTTP。
-
消息流
- 应用层->表示层->会话层->网络层->传输层->数据链路层->物理层->物理层->数据链路层->传输层->网络层->会话层->表示层->应用层。
-
消息包
- 当socket收到一个要送的数据时,发先数据进行拆分成Bit流,然后再组成(防丢失)数据包(可能会丢包)。
三、套接字
- socket是一种接口机制,可以让程序无论使用什么端口、协议,都可以从socket进出数据,它负责了进程与协议之间的连接。
- 编程模型
点对点(p2p):一对一通信。
客户机/服务器(C/S):一对多通信。 - 创建socket
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
功能:
创建socket描述符,可以把socket当作文件来看待,发送数据就是写文件,接收数据就是读文件。
domain:地址类型
AF_UNIX/AF_LOCAL/AF_FILE 本地通信(进程间通信)。
AF_INET 基本32位IP地址通信,IPv4
AF_INET6 基本128位IP地址通信,IPv6
type:通信协议
SOCK_STREAM 数据流协议,TCP
SOCK_DGRAM 数据报协议,UDP
protocol:特别通信协议,给0即可。
返回值:socket描述符,类似文件描述符。 - 通信地址
注意:函数接口定义的是sockaddr,而实际提供的是sockaddr_un或sockaddr_in
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
}
struct sockaddr_un
{
__SOCKADDR_COMMON (sun_); //地址类型 参看domain
char sun_path[108]; // socket文件的路径
};
struct sockaddr_in
{
__SOCKADDR_COMMON (sin_);
in_port_t sin_port; // 端口号 大端字节序
struct in_addr sin_addr; // ip地址 大端4字节整数
}
struct in_addr
{
in_addr_t s_addr;
};
-
绑定
socket描述符与物理通信载体(网卡或socket文件)绑定在一起。
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
sockfd:socket描述符:socket函数的返回值
addr:通信地址结构体,实际给的是sockaddr_un或sockaddr_in,需要强制类型转换。
addrlen:通信地址结构体类型的字节数,使用sizeof计算。 -
连接
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
sockfd:socket描述符
addr:通信目标地址
addrlen:通信地址结构体类型的字节数,使用sizeof计算。
返回值:在不同的编程模型下返回值意义不同,在本地通信
返回加0,失败返回-1。 -
数据接收与发送:read/write
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
recv/send与read/write功能一样,flags多了是否阻塞的功能(0阻塞,1不阻塞)。 -
关闭套接字:close
如果是网络通信,端口号并不会立即回收,大概会占用3分钟左右。 -
字节序转换
uint32_t htonl(uint32_t hostlong);
功能:把32位本机字节序转换成32位的网络字节序
uint16_t htons(uint16_t hostshort);
功能:把16位本机字节序转换成16位的网络字节序
uint32_t ntohl(uint32_t netlong);
功能:把32位的网络字节序转换成32位的本机字节序
uint16_t ntohs(uint16_t netshort);
功能:把16位的网络字节序转换成16位的本机字节序 -
ip地址转换
int inet_aton(const char *cp, struct in_addr *inp)
功能:把点分十进制的ip地址(字符串)转换成32位无符号整数,使用结构指针获取。in_addr_t inet_addr(const char *cp);
功能:把点分十进制的ip地址(字符串)转换成32位无符号整数,使用返回值直接返回。char *inet_ntoa(struct in_addr in);
功能:32位无符号整数表示的ip地址,转换成点分十进制的ip地址(字符串) -
本地通信编程模型
进程A | 进程B |
---|---|
创建套接字(AF_LOCAL) | 创建套接字(AF_LOCAL) |
准备地址(sockaddr_un) | 准备地址(sockaddr_un) |
绑定(自己的socket/地址) | 连接(connect,连接进程A的地址) |
接收数据 | 发送数据 |
关闭套接字 | 关闭套接字 |
四、基于TCP协议的C/S模型
int listen(int sockfd, int backlog);
功能:设置等待连接的最大数量
sockfd:被监听的socket描述符
backlog:等待连接的最大数量(排队的数量)
返回值:成功返回0,失败返回-1
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:等待连接sockfd连接
addr:获取连接的地址
addrlen:设置连接地址结构体长度
返回值:专门用于通信的描述符
编程模型:
Server | 操作 | Client | 操作 |
---|---|---|---|
创建socket套接字 | 创建socket套接字 | ||
准备地址 | sockaddr_in,本机地址 | 准备地址 | 服务器地址 |
绑定 | bind | ||
监听 | listen | ||
等待连接 | accept、fork | 连接 | connect |
接收请求 | read/recv | 发送请求 | write/send |
响应请求 | write/send | 接收响应 | read/recv |
关闭 | close | 关闭 | close |