一、为什么要学习网络编程?

1>进程间通信方式

内核提供三种:无名管道、有名管道、信号

System V提供三种:消息队列、共享内存、信号灯集

2> 以上通信方式,都是通过内核空间完成,在同一主机之间多个进程通信没有问题,但是,不同主机的内核空间是不同的,所以,无法做到跨主机之间多个进程之间的通信

3> 引入第七种进程间通信:套接字通信,完成跨主机多进程之间通信方式

二、课程体系

1> 本门课程一共7天时间

2> 网络通信基础(理论居多):网络通信体系结构、IP地址、MAC地址、端口号。。。

3> TCP网络通信模型、UDP网络通信模型

4> 并发服务器模型

5> 组播、广播模型

6> IO多路复用模型

7> 域套接字通信模型

8> 数据库

9> 授课过程中会做一些项目:包含C语言、数据结构、进程线程、网络编程

三、网络发展历史

发展阶段:

1.APRAnet阶段—冷战产物

2.TCP/IP协议阶段–只有TCP和IP两个协议

3.osi开放系统互联模型

4.TCP/IP协议族

3.1 APRAnet阶段

阿帕网,是Interne的最早雏形

不能互联不同类型的计算机和不同类型的操作系统

没有纠错功能

3.2 TCP/IP两个协议阶段

在计算机网络中,要做到有条不紊的交换数据,需要遵循一些事先约定好的规则。这些规则明确规定了所交换的数据的格式以及有关的同步问题。为了进行网络中的数据交换而建立的规则、标准和约定称为网络协议

联网协议:定义如何在一个网络上传输信息的一组规则

TCP/IP协议分成了两个不同的协议:

用来检测网络传输中差错的传输控制协议TCP

专门负责对不同网络进行互联的互联网协议IP

3.3 网络体系结构及OSI开放系统系统互联模型

img

3.3.1 网络体系结构概念

每一层都有自己独立的功能,单每一层都不可获取

通常把功能相近的协议组织在一起放在一层,协议栈。所以每一层中其实有多个协议

分层的好处:

1、各层之间独立,每一层不需要知道下一层如何实现,而仅仅只需要知道该层通过层间的接口所提供的服务

2、稳定,灵活性好,当任何一层发生变化时,只需要层间接口关系保持不变,而这层以上或以下层不受影响

3、易于实现和维护(知道是什么功能,就到指定层去查找)

4、促进标准化工作:每一层的功能及其所提供的服务都有了精确的说明。

5、结构上不可分割开:各层都可以采用最合适的技术来实现

3.3.2 OSI开放系统互联模型

OSI是有 ISO(国际标准化组织)提出的一个理想化模型。

OSI共有七层:

物数网传会表应。

img

注意:从上往下说也行,从下往上说也可以,但是顺序不能变。

3.3.3 TCP/IP协议族(簇)的体系结构

TCP/IP协议簇是Internet事实上的工业标准。

TCP/IP网络体系结构四层:

应用层

传输层

网络层

链路层(网络接口和物理层)

img

虽然TCP/IP体系结构只有四层,但是做的事儿和OSI的七层是一样的。

TCP/IP四层结构 和 OSI开放系统互联模型七层 的对应关系。

img

插一句:

linux内核五大功能?

内存管理:内存的分配和回收

进程管理:时间片轮转、上下文切换

文件管理:将一堆0和1转换成人类好识别的字符

设备管理:linux下一切皆文件

网络管理:网络协议栈的管理

协议:发送方和接收方都遵循的:数据发送及数据解析 的一组准则。

3.3.4 数据封包和拆包的过程

案例导入

img

img

img

img

一帧数据的说明

大小为 64–1518(包含以太网的头部14字节、尾部4字节)

如果数据大于MTU(最大传输单元,linux默认是1500),需要分成多次进行传输

可以使用指令ifconfig查看MTU最大传输单元

3.3.5 TCP/IP四层结构中常见的协议

应用层:

HTTP(Hypertext Transfer Protocol) 超文本传输协议

万维网的数据通信的基础

FTP(File Transfer Protocol) 文件传输协议

是用于在网络上进行文件传输的一套标准协议,使用TCP传输

TFTP(Trivial File Transfer Protocol) 简单文件传输协议

是用于在网络上进行文件传输的一套标准协议,使用UDP传输

SMTP(Simple Mail Transfer Protocol) 简单邮件传输协议

一种提供可靠且有效的电子邮件传输的协议

传输层:

TCP(Transport Control Protocol) 传输控制协议

是一种面向连接的、可靠的、基于字节流的传输层通信协议

UDP(User Datagram Protocol) 用户数据报协议

是一种无连接、不可靠、快速传输的传输层通信协议

网络层:

IP(Internetworking Protocol) 网际互连协议

是指能够在多个不同网络间实现信息传输的协议

ICMP(Internet Control Message Protocol) 互联网控制信息协议

用于在IP主机、路由器之间传递控制消息、ping命令使用的协议

IGMP(Internet Group Management Protocol) 互联网组管理

是一个组播协议,用于主机和组播路由器之间通信

链路层:

ARP(Address Resolution Protocol) 地址解析协议

通过IP地址获取对方mac地址

RARP(Reverse Address Resolution Protocol) 逆向地址解析协议

通过mac地址获取ip地址

注意:

每层使用的协议,由下层决定,不能乱用。

img

四、TCP和UDP异同(笔试面试)

共同点:同属于传输层的协议

TCP ----> 稳定

1> 提供面向连接的,可靠的数据传输服务

2> 传输过程中,数据无误、数据无丢失、数据无失序、数据无重复

1、TCP会给每个数据包编上编号,该编号称之为序列号

2、每个序列号都需要应答包应答,如果没有应答,则会将上面的包重复发送直到正确为止

3> 数据传输效率低,耗费资源多

4> 数据收发是不同步的

1、为了提高效率,TCP会将多个较小,并且发送间隔短的数据包,沾成一个包发送,该现象称为沾包现象

2、该沾包算法称之为Nagle算法

5> TCP的使用场景:对传输质量比较高的以及传输大量数据的通信,在需要可靠通信的传输场合,一般使用TCP协议

例如:账户登录,大型文件下载的时候

img

UDP ----> 快速

1> 面向无连接的,不保证数据可靠的,尽最大努力传输的协议

2> 数据传输过程中,可能出现数据丢失、重复、失序现象

3> 数据传输效率高,实时性高

4> 限制每次传输的数据大小,多出部分直接忽略删除

5> 收发是同步的,不会沾包

6> 适用场景:发送小尺寸的,在接收到数据给出应答比较困难的情况下

例如:广播、通讯软件的音视频

五、网络基础相关的概念

5.1 字节序

1> 不同类型的CPU主机中,在处理多字节整数序列时有两种存储方式,称为主机字节序

大端存储(big_endian):地址低位存储数据高位

小端存储(little_endiab):地址低位存储数据低位

img

2> 判断主机是大端还是小端存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include<myhead.h>

int main(int argc, const char *argv[])
{
/*使用指针验证
//定义一个整形数据
int num = 0x12345678;

char *ptr = (char *)&num; //定义一个字符指针,指向整形数据的低地址位

//判断低地址位中的值
if(*ptr == 0x12)
{
printf("bid endian\n");
}else if(*ptr == 0x78)
{
printf("little endian\n");
}else
{
printf("error\n");
}
*/


//使用共用体验证
union Endian
{
int num;
char ch;
}eun; //定义共用体变量

eun.num = 0x12345678; //给整形成员赋值

//判断字符成员中的值
if(eun.ch == 0x12)
{
printf("big endian\n");
}else if(eun.ch == 0x78)
{
printf("little endian\n");
}else
{
printf("error\n");
}

return 0;
}

3> 手动将小端存储转换为大端存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<myhead.h>

int main(int argc, const char *argv[])
{
int num = 0x12345678;

//定义一个字符指针,指向num的起始地址
char *ptr = (char *)&num;
char *qtr = ptr + 3; //定义指针指向整形数据的数据高位

//交换ptr和qtr中的内容
char temp = *ptr;
*ptr = *qtr;
*qtr = temp;

//前一个指针后移,后一个指针前移
ptr++;
qtr--;

temp = *ptr;
*ptr = *qtr;
*qtr = temp;

printf("num = %#x\n", num); //0x78563412

return 0;
}

4> 由于多字节整数需要跨主机通信,对于不同的主机存在大小端存储的不同,会导致,即使网络传输中数据无误,也会展现出错误信息

基于此,引入了网络字节序的概念,要求多字节整数,在网络中传输时,都转换为网络字节序,网络字节序是大端存储

无论主机字节序是大端还是小端存储,发送到网络之前先转换为网络字节序。当接收端接收消息后,再将网络字节序转换为主机字节序即可。

5> 系统提供了主机字节序和网络字节序相互转换的函数

网络:network

主机:host

转换:to

1
2
3
4
5
6
7
8
9
10
#include <arpa/inet.h>

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字节无符号整数由网络字节序转换为主机字节序,参数是网络字节序返回值是主机字节序

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<myhead.h>

int main(int argc, const char *argv[])
{
unsigned int num = 0x12345678; //定义4字节整数
unsigned short int key = 0x1234; //定义2字节的整数

printf("num的网络字节序值为:%#x\n", htonl(num)); //0x78563412
printf("key的网络字节序值为:%#x\n", htons(key)); //0x3412

return 0;
}

6> 何时需要进行主机字节序和网络字节序的转换

1、对多字节整数在网络中进行传输时需要进行转换

2、单字节整数不需要转换

3、字符串在网络中传输也不需要进行转换

5.2 ip地址

1> ip地址是主机在网络中的标识,每个数据包必须携带目的ip地址和原ip地址,路由器就是依照此信息进行路由选择的

2> 也是对网络标识的二级划分

3> IP地址的种类

IPv4:采用4字节无符号整数表示的ip地址,32bit 【0,2^32-1】

局域网(LAN):local area network

广域网(WAN):wide area network

IPv6:采用16字节无符号整数表示的IP地址,128bit 【0, 2^128-1】,IPv6不兼容IPv4

img

4> IP地址的划分

IP地址能够进行二级划分:将32位的IP地址分为2部分:网络号和主机号。这样额能够更加方便有效的寻径

IP = 网络号 + 主机号

网络号:确定计算机从属的网络

主机号:标识设备在该网络中的主机编号

img

注意:ABC类网络为基本类,可以分配给主机使用

D类网络为组播IP使用

E类网络为保留或实验室使用

A类地址 0.0.0.0~127.255.255.255 2^7(网络号) 2^24(主机号) 大型网络
B类地址 128.0.0.0~191.255.255.255 2^14 2^16 名地址网管中心
C类地址 192.0.0.0~223.255.255.255 2^21 2^8 校园网或企业网、家庭网
D类地址 224.0.0.0~239.255.255.255 组播地址
E类地址 240.0.0.0~255.255.255.255 保留
1
2
3
4
5
6
练习:以下ip地址可以分配给主机使用的有哪些? 
A、120.1.2.3
B、130.1.2.3
C、200.1.2.3
D、255.1.2.3

5> 点分十进制

由于ip地址是一个四字节无符号整数,单独记忆起来比较困难,索性就将每个字节对应的数字转换为十进制,以点隔开,称为点分十进制

点分十进制数据是一个字符串,但是,网络中传输时,需要使用四字节无符号整数

需要使用点分十进制和无符号整数之间相互转换的函数

1
2
3
4
5
6
7
8
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


in_addr_t inet_addr(const char *cp); //将点分十进制数据转换为4字节整数的网络字节序,参数时点分十进制,返回值时4字节整数
char *inet_ntoa(struct in_addr in); //将四字节网络字节序整数转换为点分十进制,参数时4字节整数,返回值是点分十进制

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<myhead.h>

#define IP "192.168.125.161"


int main(int argc, const char *argv[])
{
//将IP地址的点分十进制转换为4字节整数
in_addr_t temp = inet_addr(IP); //网络字节序的4字节整数

printf("temp = %x\n", temp); //得到网络字节序

printf("temp 的主机字节序:%#x\n", ntohl(temp)); //得到主机字节序


struct in_addr t;
t.s_addr = temp;


printf("4字节网络字节序对应的点分十进制为:%s\n", inet_ntoa(t)); //网络字节序转点分十进制


return 0;
}

5.3 子网掩码

1> 由于对于一个网络下面的主机号还是很庞大,为了进一步划分网络,我们可以将主机号再次进行划分为两部分,分别是网段号和主机号

2> 此时就引入的子网掩码的概念

3> 在引入子网掩码后,IP = 网络号 + 子网号 + 主机号

img

4> 子网掩码:用于ip地址的三级划分,划分时,用户可以选择划分,也可以不划分,如果不划分,就使用默认的子网掩码

定义格式:与IP地址一样长的32位整数,由一串连续的1和一串连续的0组成

默认子网掩码:1的个数与ip地址中网络号的个数保持一致,0的个数与ip地址中主机号的个数保持一致

1
2
3
4
C类网络:192.168.125.161    ---> 11111111 111111111 11111111 000000000    ----> 255.255.255.0
A类网络:58.1.2.3 ---> 11111111 000000000 00000000 00000000 ----->255.0.0.0
B类网络:150.1.2.3 ---> 11111111 11111111 00000000 00000000 ----> 255.255.0.0
D类网络和E类网络没有子网掩码

5> 子网掩码的使用:ip地址 & 子网掩码 ==> 子网网段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
192.168.125.161为例,子网掩码为255.255.255.0
11000000 10101000 01111101 10100001
&11111111 11111111 11111111 00000000
——————————————————————————————————————
11000000 10101000 01111101 00000000 --->192.168.125.0 子网网段

192.168.125.61为例,子网掩码为255.255.255.0
11000000 10101000 01111101 00111101
& 11111111 11111111 11111111 00000000
——————————————————————————————————————————
11000000 10101000 01111101 00000000 --->192.168.125.0 子网网段


192.168.125.161为例,子网掩码为255.255.255.128
11000000 10101000 01111101 10100001
&11111111 11111111 11111111 10000000
——————————————————————————————————————
11000000 10101000 01111101 10000000 --->192.168.125.128 还可以写成:192.168.125.128/25


192.168.125.61为例,子网掩码为255.255.255.128
11000000 10101000 01111101 00111101
& 11111111 11111111 11111111 10000000
________________________________________
11000000 10101000 01111101 00000000 --->192.168.125.0 还可以写成:192.168.125.0/24

img

总结:

子网网段的个数 = 2^(子网中1的个数)

子网网段下的主机个数 = 2^(子网中0的个数)

1
2
某个公司有4 部门:行政 研发 售后 营销,每个部门20台电脑接入公司局域网交换机。
如果在192.168.125.0网段划分每个部分的子网,写出所有可用的子网掩码?子网的地址范围是什么?

img

6> 特殊的网络

当前网络:网络加主机号为0的ip地址,例如:192.168.125.0

广播地址:网络号加主机号为255的ip地址,例如:192.168.125.255

网关地址:网络号加主机号为1的ip地址,例如:192.168.125.1

5.4 端口号(重要) —> port

1> 端口号是能够实现网络端对端的通信

2> 是主机中某个进程的标识,由于某个进程关闭后,再打开,pid会不断更改,所以,在启动一个进程时,可以指定端口号,标识该进程

3> 端口号是一个2字节的无符号整数,取值范围[0,65545]

4> 端口号的分类:

众所周知的端口号:

​ 0~1023端口我们编程时候不要使用,是那些”VIP“应用程序占了

​ TCP 21端口:FTP文件传输服务

​ TCP 23端口:TELNET终端仿真服务

​ TCP 25端口:SMTP简单邮件传输服务

​ TCP 110端口:POP3邮局协议版本3

​ TCP 80端口:HTTP超文本传输服务

​ TCP 443端口:HTTPS加密超文本传输服务

​ UDP 53端口:DNS域名解析服务

​ UDP 69端口:TFTP文件传输服务

TCP和UDP的端口号是相互独立的

可以使用的:1024~49151,就是我们平时编写服务器使用的端口号

临时端口号:49152~65535,这部分是客户端运行时候动态选择的

5.5 域名解析

由于使用IP地址来指定计算机不方便人们记忆,且输入时候容易出错,用字符标识网络种计算机名称方法。

这种命名方法就像每个人的名字,这就是域名(Domian Name)

域名服务器(Domain Name server):用来处理IP地址和域名之间的转换。

域名系统(Domain Name System,DNS):域名翻译成IP地址的软件

一个域名,可以绑定多个ip

域名结构

​ 例如域名 www.baidu.com.cn 从右向左看

​ cn为高级域名,也叫一级域名,它通常分配给主干节点,取值为国家名,cn代表中国

​ com为网络名,属于二级域名,它通常表示组织或部门

​ 中国互联网二级域名共40个,edu表示教育部门,com表示商业部门,gov表示政府,军队mil等等

​ baidu为机构名,在此为三级域名,表示百度

​ www:万维网world wide web,也叫环球信息网,是一种特殊的信息结构框架。

总结:

子网网段的个数 = 2^(子网中1的个数)

子网网段下的主机个数 = 2^(子网中0的个数)

1
2
某个公司有4 部门:行政 研发 售后 营销,每个部门20台电脑接入公司局域网交换机。
如果在192.168.115.0网段划分每个部分的子网,写出所有可用的子网掩码?子网的地址范围是什么?

5.4 端口号(重要) —> port

1> 端口号是能够实现网络端对端的通信

2> 是主机中某个进程的标识,由于某个进程关闭后,再打开,pid会不断更改,所以,在启动一个进程时,可以指定端口号,标识该进程

3> 端口号是一个2字节的无符号整数,取值范围[0,65545]

4> 端口号的分类:

众所周知的端口号:

​ 0~1023端口我们编程时候不要使用,是那些”VIP“应用程序占了

​ TCP 21端口:FTP文件传输服务

​ TCP 23端口:TELNET终端仿真服务

​ TCP 25端口:SMTP简单邮件传输服务

​ TCP 110端口:POP3邮局协议版本3

​ TCP 80端口:HTTP超文本传输服务

​ TCP 443端口:HTTPS加密超文本传输服务

​ UDP 53端口:DNS域名解析服务

​ UDP 69端口:TFTP文件传输服务

TCP和UDP的端口号是相互独立的

可以使用的:1024~49151,就是我们平时编写服务器使用的端口号

临时端口号:49152~65535,这部分是客户端运行时候动态选择的

5.5 域名解析

由于使用IP地址来指定计算机不方便人们记忆,且输入时候容易出错,用字符标识网络种计算机名称方法。

这种命名方法就像每个人的名字,这就是域名(Domian Name)

域名服务器(Domain Name server):用来处理IP地址和域名之间的转换。

域名系统(Domain Name System,DNS):域名翻译成IP地址的软件

一个域名,可以绑定多个ip

域名结构

​ 例如域名 www.baidu.com.cn 从右向左看

​ cn为高级域名,也叫一级域名,它通常分配给主干节点,取值为国家名,cn代表中国

​ com为网络名,属于二级域名,它通常表示组织或部门

​ 中国互联网二级域名共40个,edu表示教育部门,com表示商业部门,gov表示政府,军队mil等等

​ baidu为机构名,在此为三级域名,表示百度

​ www:万维网world wide web,也叫环球信息网,是一种特殊的信息结构框架。

本章完