一、OSI 7层模型,TCP/IP 4层模型 5层模型。 以及每一层的功能(重点:第三层 第四层)
答:
7层模型(①物理层:二进制比特流传输,②数据链路层:相邻结点的可靠传输,③网络层:寻址和路由选择,④传输层:端到端的可靠传输,⑤会话层:主机之间会话管理,⑥表示层:数据表示,加密与压缩,⑦应用层:提供各种网络应用接口)
5层模型(①物理层,②数据链路层,③网络层,④传输层,⑦应用层)
4层模型(①网络接口和物理层或网络访问层:ip地址与物理地址的映射(MAC),以及将上一次的ip报文封装成帧,转换成二进制比特流传输,③网络层,④传输层,⑦应用层)
网络接口和物理层:网络访问层
二、MAC地址:48bit全球唯一。 改变网络环境后MAC地址变不变,IP地址变不变
答:MAC不变,IP改变
2.1 ARP:通过ip地址获取对应的mac地址
2.2 RARP:通过mac地址获取对应的ip地址
2.3 MTU MSS,分别多大,有什么作用
答:MTU(最大传输单元):物理接口提供给上层最大一次传输数据的大小,规定了数据链路层所能传送最大数据长度,最大为1500bytes。MSS(最大报文长度):TCP提交给IP层最大分段大小,指TCP报文所允许传送数据部分最大长度,不包含TCP头,MSS是TCP来限制应用层最大发送字节数,若MTU=1500,则MSS最大为1460bytes
三、网络层:
- IP协议 : 路由器工作在哪一层:网络层
- ICMP :英特网控制管理协议,用于在IP主机、路由器之间传递控制消息
- IGMP:英特网分组管理协议,组播,广播
四、传输层:
4.1 TCP UDP
答:TCP(传输控制协议):提供面向连接的,一对一的,可靠数据传输协议。UDP(用户数据报协议):提供无连接的,不可靠的,尽力的传输协议(效率高)
4.2 TCP和UDP有什么异同点
答:相同点:是同属于传输层的协议。不同点:
TCP:
- TCP是面向连接的,可靠的数据传输协议
- TCP提供数据无误,数据无失序,数据无丢失,数据无重复到达的通信
- 传输效率低,耗费资源多
- 数据的收发是不同步的,或出现粘包的情况
UDP:
- UDP是面向无连接的,不可靠的,尽力的数据传输协议
- 数据有可能在传输过程中丢失、失序、重复
- 传输效率高
- 数据的收发是同步的,不存在粘包现象
- 限制每次传输的数据大小,超出部分直接删除
五、IP地址:
5.1 IP地址分类:2类
答:IPv4:采用4个字节的无符号整数,共32bit来存储IP地址。IPv6:采用16字节的无符号整数,共128bit来存储IP地址
5.2 二级IP地址划分:二级IP地址 = 网络号 + 主机号 哪几类可以分配给主机使用。
答:A类:0.0.0.0~127.255.255.255
B类:128.0.0.0~191.255.255.255
C类:192.0.0.0~223.255.255.255
D类:224.0.0.0~239.255.255.255
E类:240.0.0.0~255.255.255.255
ABC类为基本类,IP地址分配给主机使用,D类不表示网络,用于特殊用途,例如:组播。E类不表示网络,保留或者实验室使用。
5.3 网络地址和广播地址:
答:网络地址 = 有效网络号 + 全是0的主机号,例如192.168.122.92 网络地址为192.168.122.0
广播地址 = 有效网络号 + 全是1的主机号,例如192.168.122.92 广播地址为192.168.122.255
5.4 子网掩码:默认子网掩码,子网网段个数,主机号,可以用主机号,所有可用主机号。 题型详情看笔记。
答:三级IP地址划分:利用子网掩码可以将主机号再次划分,可以划分部分为2^n,IP = 网络号 + 子网号 + 主机号
子网掩码格式:子网掩码的长度与IP地址长度一样是32位无符号整数,由一串连续的1后面跟着连续的0组成
IP地址 & 子网掩码 = 子网网段
子网网段个数 = 2^(子网掩码中多加的1的个数)
每个子网网段中主机号的个数 = 2^(子网掩码剩余0的个数)
六、字节序:请简述字节序的概念,并用共用体(联合体)的方式判断本机字节数
答:字节序是指不同类型CPU主机内存存储多字节整数序列的方式,例如:short,int,long。字节序分为大端字节序与小端字节序,小端字节序:低地址存储低字节,高地址存储高字节。大端字节序:低地址存储高字节,高地址存储低字节。用共用体的方式判断本机字节序:
#include <stdio.h>
union t
{
int a;
char b;
};
int main(int argc,const char argv[])
{
union t test;
test.a = 1;
if(1 == test.b)
printf("这是小端存储\n");
else if(0 == test.b)
printf("这是大端存储\n");
}
七、TCP
7.1 TCP流程图
7.2 send函数能否替换成其他函数
答:可以,当send中的flag == 0时,send函数可以替换成write,也可以替换成sendto,此时sendto最后两个参数分别为NULL和0
7.3 recv函数能否替换成其他函数
答:可以,当recv中的flag == 0时,recv函数可以替换成read,也可以替换成recvfrom,此时recvfrom最后两个参数为NULL
八、UDP
8.1 UDP的流程图
8.1 recvfrom函数能否替换成其他函数
答:可以,当flag == 0且最后两个参数都为NULL时,可以替换成recv,read函数
8.2 sendto函数能否替换成其他函数 ----> connect
答:可以,当flag == 0时,可以替换成send,write函数,但前提是得先调用connect函数
8.3 udp中能否调用connect函数。(与TCP的对比,优点)
答:UDP中,可以调用connect函数。
- TCP中的connect函数会产生三次握手,将客户端与服务器相连,UDP中的connect函数不会产生连接,它仅仅将对端的IP和端口号记录到内核套接字中,此时UDP只能与记录的对端进行通信
- TCP中的connect函数只能调用一次,UDP中的connect函数可以调用多次,但会刷新内核中对端的IP和端口号,如果想要清空内核中对端的地址信息,则需要将地址信息结构体中sin_family设置成AF_UNSPEC,再调用connect
- 当UDP采用connect函数后,sendto函数可以用send,write替换
- UDP调用connect函数能够提升传输效率
- UDP调用connect函数能够增加传输稳定性
九、广播IP和组播IP(流程)
9.1.1 广播发送方
- socket 创建报式套接字
- setsockopt 设置允许广播 level:SOL_SOCKET optname:SO_BROADCAST
- bind 非必须绑定
- 填充接收方的地址信息结构体,给sendto函数使用,IP:广播IP 与接收方绑定的一致(ps:不能填0.0.0.0)PORT:1024~49151,与接收方绑定的一致
- sendto 发送
9.1.2 广播接收方
- socket 创建报式套接字
- 填充接收方自身的地址信息结构体,给bind函数使用
- IP:绑定广播IP(192.168.123.255 或者 255.255.255.255 或者0.0.0.0)
- 0.0.0.0:一旦绑定到套接字上,会将本机所有可用IP地址都绑定到套接字上。例如:
- ifconfig出来的本机IP 192.168.122.120
- 本地环回IP: 127.0.0.1
- 广播IP
- 组播IP
- 0.0.0.0:一旦绑定到套接字上,会将本机所有可用IP地址都绑定到套接字上。例如:
- PORT:1024~49151。
- IP:绑定广播IP(192.168.123.255 或者 255.255.255.255 或者0.0.0.0)
- bind 必须绑定
- recvfrom 接收数据
9.2.1 组播发送方
- socket 创建报式套接字
- bind 非必须绑定
- 填充接收方的地址信息结构体,给sendto函数使用,IP:组播 与接收方绑定的一致(ps:不能填0.0.0.0),PORT:1024~49151,与接收方绑定的一致
- sendto 发送
9.2.2 组播接收方
- socket 创建报式套接字
- setsockopt 加入多播组 level:IPPROTO_IP optname:IP_ADD_MEMBERSHIP
- 填充接收方自身的地址信息结构体,给bind函数使用
- IP:绑定组播IP,与加入的组播一致(224.0.0.0 - 239.255.255.255 或者 0.0.0.0)
- 0.0.0.0:一旦绑定到套接字上,会将本机所有可用IP地址都绑定到套接字上。例如:
- ifconfig出来的本机IP 192.168.122.120
- 本地环回IP: 127.0.0.1
- 广播IP
- 组播IP
- 0.0.0.0:一旦绑定到套接字上,会将本机所有可用IP地址都绑定到套接字上。例如:
- PORT:1024~49151。
- IP:绑定组播IP,与加入的组播一致(224.0.0.0 - 239.255.255.255 或者 0.0.0.0)
- bind 必须绑定
- recvfrom 接收数据
十、多进程并发服务器 和 多线程并发服务器模型
10.1 多进程并发服务器
void handler(int sig){
while(waitpid(-1, NULL, WNOHANG) > 0);
}
signal(17, handler);
sfd = socket();
bind();
listen();
while(1){
newfd = accept();
if(fork() == 0){
close(sfd);
while(1){
recv();
send();
}
close(newfd);
exit(0);
}
close(newfd);
}
close(sfd);
10.2 多线程并发服务器
sfd = socket();
bind();
listen();
while(1){
newfd = accept();
pthread_create(&tid, NULL, deal_cli_msg, &info);
pthread_detach(tid);
}
close(sfd);
void* deal_cli_msg(void* arg){
newfd = arg->newfd;
cin = arg->cin;
while(1){
recv();
send();
}
close(newfd);
pthread_exit();
}
十一、IO多路复用的分类?请简述其中一种的流程(原理)?
答:IO多路复用分为select、poll、epoll,select的TCP服务器模型
sfd = socket();
bind();
listen();
while(1)
{
tempfds = readfds
select(maxfd+1,&tempfds,NULL,NULL,NULL);
for(int i=0;i<maxfd;i++)
{
if(FD_ISSET(i,&tempfds) == 0) continue;
if(0 == i)
{
fgets();
}
else if(sfd == i)
{
newfd = accept();
FD_SET(new,&readfds);
maxfd = maxfd > newfd ? maxfd : newfd;
}
else
{
res = recv();
if(0 == res)
{
close(i);
FD_CLR(i,&readfds);
while(FD_ISSET(maxfd,&readfds) == 0 && maxfd-- > 0)
continue;
}
send();
}
}
}
close(sfd);