目录
- 一、网络初识
- 1.协议
- 2.OSI七层模型
- 3.TCP/IP五层模型
- 4.通讯原理图解
- 二、socket
- 1.源IP和目的IP
- 2.端口号
- 3.端口号和进程ID
- 4.初识TCP、UCP协议
- 5.网络字节序
- 三、socket接口
- 1.常见API
- 2.sockaddr结构
一、网络初识
网络在计算机中的位置。
网络也是一种软件,所以网络也是可以分层的。
1.协议
协议" 是一种约定。
计算机之间的传输媒介是光信号和电信号. 通过 “频率” 和 “强弱” 来表示 0 和 1 这样的信息。要想传递各种不同的信息, 就需要约定好双方的数据格式 。
2.OSI七层模型
1.OSI(open System Interconnection,开放系统互连)七层网络模型称为开放式系统互联参考模型,是一个逻辑上的定义和规范;
2.把网络从逻辑上分为了7层,每一层都有相关,相对应的物理设备,比如路由器,交换机;
3.OSI七层模型市一中框架的设计方法,其主要的功能就是帮助不同类型的主机实现数据传输。
4.它的最大优点市将服务,接口和协议这三个概念明确地区分开来,概念清楚,理论也比较完整,通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯。
5.但是,它既复杂也不使用,我们按照TCP/IP四层(五层)模型学习
3.TCP/IP五层模型
TCP/IP是一组协议的代名词,它还包括许多协议,组成了TCP/IP协议簇,TCP/IP通讯协议采用了5层的层级结构,每一层都呼叫他的下一层所提供的网络来完成自己的需求。
物理层: 负责光/电信号的传递方式. 比如现在以太网通用的网线(双绞 线)、早期以太网采用的的同轴电缆(现在主要用于有线电视)、光纤,
现在的wifi无线网使用电磁波等都属于物理层的概念。物理层的能力决定了最大传输速率、传输距离、抗干扰性等. 集线器(Hub)工作在物理层。数据链路层: 负责设备之间的数据帧的传送和识别. 例如网卡设备的驱动、帧同步(就是说从网线上检测到什么信号算作新帧的开始)、冲突检测(如果检测到冲突就自动重发)、数据差错校验等工作.
有以太网、令牌环网, 无线LAN等标准. 交换机(Switch)工作在数据链路层。网络层: 负责地址管理和路由选择. 例如在IP协议中, 通过IP地址来标识一台主机, 并通过路由表的方式规划出两台主机之间的数据传输的线路(路由). 路由器(Router)工作在网路层。
传输层: 负责两台主机之间的数据传输. 如传输控制协议 (TCP), 能够确保数据可靠的从源主机发送到目标主机。
应用层: 负责应用程序间沟通,如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet)等. 我们的网络编程主要就是针对应用层。
4.通讯原理图解
二、socket
1.源IP和目的IP
对于一个报文来讲,即表示从哪里来,到哪里去。
最大的意义:指导一个报文该如何进行路径选择。
2.端口号
端口号(port)是传输层协议的内容.
端口号是一个2字节16位的整数;
端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理;
IP地址 + 端口号能够标识网络上的某一台主机的某一个进程;
一个端口号只能被一个进程占用 。
3.端口号和进程ID
我们知道pid 表示唯一一个进程; 此处我们的端口号也是唯一表示一个进程. 那么这两者之间是怎样的关系?
一个进程可以绑定多个端口号; 但是一个端口号不能被多个进程绑定 。
IP地址(公网IP)唯一的标识互联网中的唯一一台主机,端口号唯一的标识主机上的唯一一个进程;即 IP+port端口号 = 互联网中的唯一的一个进程。
要先通信,本质为: 先找到目标主机。再找到该主机上的服务(进程)。
所以在互联网世界中,其实就是一个进程间通信。
4.初识TCP、UCP协议
tcp协议:传输层协议、有连接、可靠传输、面向字节流。
udp协议:传输层协议、无连接、不可靠传输、面向数据报。
tcp虽然是可靠传输,udp是不可靠传输,不代表tcp就比udp协议更好,而需要根据应用场景合理选择。
5.网络字节序
内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏 移地址也有大端小端之分, 网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢?
发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;
接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址.
TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节.
不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据;
如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即可;
为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t htohl(uint32_t netlong);
uint16_t htons(uint16_t netshort);
这些函数名很好记,h表示host,n表示network,l表示32位长整数,s表示16位短整数。
例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回;
如果主机是大端字节序,这些 函数不做转换,将参数原封不动地返回。
三、socket接口
1.常见API
// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
// 绑定端口号 (TCP/UDP, 服务器)
int bind(int socket, const struct sockaddr *address,socklen_t address_len);
// 开始监听socket (TCP, 服务器)
int listen(int socket, int backlog);
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address,socklen_t* address_len);
// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
网络通信的标准方式有很多种,比如:基于ip的网络通信:AF_INET,原始套接字,域间套接字。
它们都能使用同一套接口进行通信。而sockaddr就是这样的一种通用结构。
2.sockaddr结构
上面所提到的所有接口中,都只能用sockaddr结构,所以当使用网络套接字(AF_INET)和域间套接字(AF_UNIX)时都必须要强转成sockaddr使用。其本质类似于多态。
socket
socket的作用: 为网络通信创建一个 socket 文件。
socket的参数:
① domain:指定协议家族。我们选择 AF_INET 。
② type:指定套接字类型。对于 TCP SOCK_STREAM ,应选择 ;对于 UDP ,应选择 SOCK_DGRAM 。
③ protocol:指定协议类型。在 TCP 和 UDP 中,我们设为 0 即可。
socket的返回值:
① 成功,返回一个 socket 文件描述符。
② 错误,返回 -1 。
头文件
bind
bind的作用: 将本地地址和一个 socket 文件进行绑定。
bind的参数:
① sockfd:传入 socket 文件描述符。
② addr:用于指定本端的 socket 信息。
③ addrlen:用于指定本端的 socket 信息的大小。
bind的返回值:
① 成功,返回 0 。
② 错误,返回 -1 。
头文件
recvfrom
recvfrom的作用: 从一个 socket 文件接收数据。
recvfrom的参数:
① sockfd:传入 socket 文件描述符。
② buf:用于存放读到的数据的用户层缓冲区。
③ len:用户层缓冲区的大小。
④ flags:读的方式。我们这里默认设为 0 即可。
⑤ src_addr:输入输出型参数,用于获取对端的 socket 信息。
⑥ addrlen:输入输出型参数,用于获取对端的 socket 信息的大小。
recvfrom的返回值:
① 成功,返回接收的字节数(当对端连接关闭时,返回 0)。
② 错误,返回 -1 。
参数
sendto
sendto的作用: 从一个 socket 文件发送数据。
sendto的参数:
① sockfd:传入 socket 文件描述符。
② buf:用于发送数据的用户层缓冲区。
③ len:发送数据的长度。
④ flags:发送的方式。我们这里默认设为 0 即可。
⑤ dest_addr:目标对端的 socket 信息。
⑥ addrlen:目标对端的 socket 信息的大小。
sendto的返回值:
① 成功,返回发送的字节数。
② 错误,返回 -1 。
头文件
listen
listen的作用: 设置一个socket文件为监听状态,允许该socket文件被连接。
listen的参数:
①sockfd:传入socket文件描述符
②backlog:设置连接队列的最大长度
listen的返回值:
①成功,返回0
②失败,返回-1
头文件
accept
accpet的作用: 从一个socket文件接受连接。
accept的参数:
①sockfd:传入listen状态的socket文件描述符
②addr:输入输出型参数,获取对端的socket信息
③addrlen:输入输出型参数,获取对端的socket信息的大小。
accept的返回值:
①成功,返回一个文件描述符
②失败,返回-1;
头文件
connect
connect的作用:在一个socket文件上向目标发起连接
connect的参数:
①sockfd:传入socket文件描述符
②addr:目标对端的socket信息
③addrlen:目标对端的socket信息的大小
connect的返回值:
①成功,返回0
②失败,返回-1
头文件