目录
一、网络
OSI 七层模型
1.物理层
2.数据链路层 交换机----MAC地址
3.网络层 IP(路由器)----主机
4.传输层 端口号
5.会话层
6.表示层
7.应用层
TCP/IP四层模型
1.数据链路层
2.网络层
3.传输层
4.应用层
(5层加物理层)
网络字节序:大端存储
主机 : 小端存储
常用网络协议:
1.应用层 https http(超文本传输加密协议) DNS(域名与IP n--n)(域名解析协议) pop3(邮件传输协议) FTP(文件传输协议) TFTP
2.传输层 UDP TCP
3.网络层 IP ICMP(网际控制文本协议)(ping) 路由器的工作原理
4.数据链路层 ARP(d地址解析协议IP--MAC) RARP(MAC--IP)
ip的子网划分:
0~255 总共256 其中0是留给默认网关的 不能作为主键ip
255是留给广播用的
实际上总共是254
端口号:
TCP/IP传输使用TCP/IP协议栈
若不到这个范围则进行填充 若超出范围则进行拆包
二、UDP
1.面向无连接(1-1 1-n广播 和组播)(广播:整个范围 组播:整体内的指定范围)
2.数据报文(固定大小)
3.丢包 乱序
4.效率高
recvfrom 和 sendto的过程:
电脑中每个进程内分为用户区和内核区
每个套接字都有两个空间,一个是发送缓冲区,一个是接收缓冲区
一个电脑发送 一个电脑接收
套接字默认情况下是阻塞的
阻塞:直到做完任务才返回(来数据了 停在那不动了)直到发送完和接收完才返回(一直等结果的)
阻塞情况下sendto把数据放到发送缓冲区内 完整的放进去之后才返回,然后通过内核的发送缓冲区和网卡传出去,只要数据从网卡传出去,就会把它从发送缓冲区删掉; 发送数据之后,先到接收端的接收缓冲区,reecvfrom一直阻塞,直到拿到数据才会返回 。
注意:若发送的数据大于以太网帧的范围则进行拆包,传输过程中可能会丢包和乱序
丢包:例如拆成2个包之后 发送端发出去之后 数据删除 若路由过程中生命周期减为0 那么这两个包在网络中就丢失了
乱序:路由路径的选择不同
非阻塞:试图往里放,不管放没放进去,通过返回值看(一段时间内有返回值得)
三、TCP
TCP:
1.面向连接(三次握手,四次挥手)1-1
2.数据流(可任意拆分)
3.安全可靠(重传校验,滑动窗口,拥塞控制)
解决粘包问题:
1.特殊字节结尾
2.固定包大小
3.在包头加包长度(更灵活)
4.短连接
下面请看详细代码:
//服务器端:
//接收包大小
nReNum = recv(sockWaiter,(char*)&nPackSize,sizeof(int),0);
if(nReNum <= 0)
{
continue;
}
pszbuf = new char[nPackSize];
int offset = 0;
//接收包内容
while(nPackSize)
{
nReNum = recv(sockWaiter,pszbuf+offset,nPackSize,0);
if(nReNum > 0)
{
nPackSize -= nReNum;
offset += nReNum;
}
cout << "Client say : " << pszbuf <<endl;
delete []pszbuf;
pszbuf = nullptr;
//用户端:
char szbuf[1024];
int nPackSize = sizeof (szbuf);
int nRecvNum;
while(1)
{
cin >> szbuf;
//发送包大小
send(sockClient,(char*)&nPackSize,sizeof(int),0);
//发送包内容
send(sockClient,szbuf,sizeof(szbuf),0);
nRecvNum = recv(sockClient,szbuf,sizeof(szbuf),0);
if(nRecvNum > 0)
{
cout << "Server say:" << szbuf << endl;
}
}
三次握手和四次挥手:(三次握手过程交换了序号和滑动窗口的大小)
注意:滑动窗口是在三次握手的过程中确定的窗口大小
拥塞控制:
判断当前是否拥塞:是否收到连续三个重复确认
是:网络还ok 普通丢包 执行快重传 快恢复
否:网络糟糕 需要执行慢启动重新来
同步阻塞+多线程 :为每一个套接字都匹配一个线程 虽然是实时的 但是浪费资源
同步非阻塞 :单线程处理多个套接字 相对来说节省资源 但是会有延迟效率可能不高
四、IO多路复用模型 select
五、异步选择、异步事件
异步事件性能更优
六、完成端口
唯一的异步非阻塞 但步骤繁杂
考虑高并发 实时 可可、使用完成端口