网络
在物理层以上均是使用软件相连
串口与串口之间有三条总线:控制总线,数据总线 ,地址总线
数据总线有两条,一条收,一条发,频率是一样的
协议
网络协议为计算机网络中进行数据交换而建立的规则、标准或约定的集合。简单说协议就是规矩
有线网都是以EN开头,无线网都是以WL开头
BROADCAST 广播,多播
LOOPBACK 本地环回
mtu 一帧能发多少个字节
RX 收取
TX 发送
链路层
链路层链路层主要是解决物理链路的问题,必须要有网卡
网络层
IP地址和子网掩码相与可以算出网段
端口号既可以映射机器,也可以映射自身的进程
链接DHCP服务器
DHCP:自动分配IP地址
- 发一个DHCP请求
- DHCP服务器返回一个DHCP
- 机器获取IP
传输层
解决发送数据的问题
在X上加数均为Cli向Server的请求,Server的回复
在Y上加数均为Server向Cli的请求,Cli对Server的回复
如果攻击者获取随机数,则可以进行欺骗,解决方法:加密
半连接状态:谁干完活谁先断,没干完的继续发送
隔离性:双方通信,别人无法插入
连续性:双方通信按照一定的顺序
URG 紧急指针,1为紧急数据,不排序,先处理,紧急关闭端口时可以使用
RST 能保证立刻断开
选项信息:比如序列号等信息,最多40字节
Socket
socket 套接口
sock 接口卡
服务端
Linux查看进程ID号:ps -ef|grep xxx
查看网络状态:netstat -anlp|grep 27423(进程ID)
ServerSock ss=new ServerSock(8888);//端口号,需要端口号或需要端口,数,IP地址
While(true){//不断监听
Socket s=ss.accept();//监听
InputStream in=s.getInputStream();
int len;
byte[] bs=new byte[5];
if((len=in.read(bs))>0){
System.out.println(new String(bs));
}
OutputStream out=s.getOutputStream();
out.write("ok".getBytes);
out.flush;
s.close;
}
最大并发链接数:一个服务器可以抗多少个客户端链接
客户端
Socket s=new Socket("127.0.0.1",9999);
OutputStream out=s.getOutputStream();
out.write("hello".getBytes());
out.flush();
InputStream in=s.getInputStream();
int len;
byte[] bs=new byte[5];
if((len=in.read(bs))>0){
System.out.println(new String(bs));
s.close;
}
将请求接到后,可以用线程池去接,服务端几乎不会用bio
Socket8大参数
client与server都有一个sendbuffer与resbuffer
resbuffer中存着对端的IP和端口,以及我端的IP和端口
如果对端的resbuffer写满了,会造成内存字节溢出;回环;内存从头覆盖重写,会造成数据的丢失
nagle算法:发送端sendbuffer写满后,才发到对端;对端的resbuffer如果不够,则向下兼容,sendbuffer只能小于等于对端的resbuffer
resbuffer如果满了就将内容拷贝到另一个内存,拷贝中如果对端sendbuffer要发送数据,则由nagle算法算出最大发送数据大小,进行发送,不断的计算,不断的计算,这就是叫滑动窗口
滑动窗口能控制流量,这就是限流,解决方法,改变滑动窗口,改变缓冲区
-
参数一:Sock.setTcpNoDelay(true);
发送端不管nagle算法,多少都发
好处:及时的发送
坏处:容易使对方的resbuffer爆满 -
参数二、三:Socket.setSendBuffersize(100);
Socket.setReceiveBuffersize(100);
设置发送/接收端缓存区的大小 -
参数四:Socket.setSoTimeout(60);
读超时,单位是ms
当时间段内没有收到数据,断开连接,报错(-1) -
参数五:Socket.setKeepAlive(true);
要在客户端与服务端都设为true
长时间不与服务端通信,就把客户端踢了
客户端报错:broken pipe(被破坏的管道)
说明服务端认为客户端已死,已经被客户端踢了
-
参数六:Socket.setSolinger(true,60);
自动引爆
在客户端与服务端同时设置这参数后,有任何一端有close方法时,会发送RST(定时引爆),不会回信,到点自动断开,但是不安全 -
参数七:Sock.setReuseAddress(true);
端口复用,端口被占用后,就重启一个端口 -
参数八:Sock.setOOBInline(true);
允许发送紧急指针,两端设为true后,允许使用紧急指针
Sock.sendUrgentData(65);
发送紧急执政,只能发一个字节
效率最高,发了就能立刻处理
粘包 拆包问题
avaliable为滑动窗口
以包的方式发送数据,万一中途断开,会造成发送数据不全的问题
滑动窗口过小,发送不过去的字节会乱码,如中文占三个字节,滑动窗口不是不是以三的倍数,包被拆成了两部分,也会造成乱码,此问题被称为粘包(拆包)问题
sendBuffer与resBuffer不对称也会造成此问题
解决方法:
变长方式(复杂指令)
一个字节一个字节的发,设定一个可变长数组,有字节就变长,读到特定的终止符时就终止读
效率低
定长方式(精简指令)
每次接收一个固定长度的字节数
会话层
session
Socket其实就是会话层的API
表示层
如何解释数据,如文件的格式
所以表示层与会话层的协议其实也是应用层的协议,所以上三层统称应用层
应用层
HTTP:超文本传输协议
明文:某种字符编码正常显示字符内容的编码方式
非明文:用所有编码方式都解析不出来,则为密文
java序列化表示层为密文,json,xml为明文协议,字符串协议
半连接:一边忙完了就发FIN,单方面不再发送数据,半连接资源利用率高,发展出了HTTP请求
requst/response(请求报文与响应报文)
request就是客户端给我发的报文,response就是未来拼好的对象,会反序列化,我给服务器发的报文,服务器给我发的报文,反序列化为request对象
-
请求报文
请求头(请求行)
通用头(我能接受什么格式的响应)
实体头(报文体怎么看)
\r\n(回车换行)
报文体(请求的内容) -
请求头格式
请求命令 url地址 http1.1
请求命令:accpt-encoding:gzip
accpt-language:zh
context-length:7 -
http8大请求
get/post/del/put/trace/option/connection/head
大多数服务器都不做del和put
trace:服务器版本
head:请求内容服务器能接收什么,什么版本等等
- 响应报文
响应头
通用头
实体头
\r\n
报文体
回的数字信息:
100 包没发完
200 2开头的为成功
300 转发
301 302 请求的东西不在此服务器,回url使请求跳转
303 请求的东西之前在,回ulr使请求跳转
304 请求内容请求过,缓存在本地,请求自己在本地找
400 客户端错误
400 401 402 认为请求是个骗子,不回应
404 页面不存在
405 在墙外,防火墙拦截
500 服务器错误
501 服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码
502 Bad Gateway错误、504 Bad Gateway timeout 网关超时
503 服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。(服务不可用)
504 表示超时,也就是客户端所发出的请求没有到达网关,请求没有到可以执行的php-fpm
505 服务器不支持请求中所用的 HTTP 协议版本。(HTTP 版本不受支持)