OSI七层模型:
应用层:http协议,电子文件传输,文件服务器等。
表示层: 解决我们不同系统之间语法的通讯兼容问题
会话层:建立与应用程序的会话连接
传输层:提供端口号和传输的协议(TCP和UDP)
网络层:为我们的数据实现路由(比如路由器,交换机)
数据链路层:传输的地址的桢以及错误的检测
物理层:所谓的物理层都是以二进制的形式,在屋里机器上实现传输(光纤,专线,各种物理介质实现)
什么是Socket技术
任何的编程语言都是支持socket(网络编程的技术)技术开发。目的就是解决两个应用程序通讯的问题:注意socket不属于某种协议,只是网络编程技术。
Socket技术支持两种协议(TCP和UDP)
UDP和TCP区别
tcp协议是一个面相连接的可靠协议,因为建立连接的时候必须通过三次握手才可以实现数据传输:所以数据不会丢失。(应用场景:http协议,rpc框架)
udp协议是一个面向无连接的协议,udp在通讯的时候不需要知道对方在不在,属于不可靠传输。可能会存在数据丢失问题。(应用场景某些聊天软件,消息提醒等等)
tcp三次握手:白话文版
(1)第一次握手:客户端会向服务器端发送消息:你人在否?
(2)第二次握手:服务器端接收到了客户端咨询的(你人在否)
(3)第三次握手:客户端收到服务器端回复(我在的了)客户端就会给服务器端发送消息 ,好的我们开始建立传输数据。
Syn(建立连接)
Ack(确认标记)
fin(终止标记)
(1)第一次握手:客户端会向服务器到端 发送代码syn=1,随机会产生一个随机数SEQ= X发送到我们的服务器端。
(2)第二次握手:服务器端确认收到sy和x值,回复给客户端ack=x+1和seq = y(随机数)发送给客户端
(3)第三次握手:客户端接收syn,ack,y值之后向服务器端发送ack=y+1,此包发送完毕之后就可以 开始建立连接。
既然有三次挥手,那么就有四次挥手:
三次挥手主要目的是,确保连接可靠
四次挥手 可靠关闭连接
白话文版:
第一次挥手:客户端向服务端发送一个释放连接通知
第二次挥手:服务端接收到释放通知之后,告诉给客服端说等待一下,因为可能存在有其他的数据没有发送完毕,等待数据全部传输完毕之后就开始关闭连接。
第三次挥手:服务器端所有的数据发送完毕之后,就告诉客户端现在可以释放连接了。
第四次挥手:客户端确认是最终释放连接通知,好的,就像服务区端发送我们可以分开了。
关闭连接:
第一次挥手:客户端向服务器端发送释放的报文,停止发送数据fin=1,生成一个序列号seq=u;
第二次挥手:服务器端接收到释放的报文后,发送ack=u+1:随机生成seq=v给客户端:当前状态为关闭等待状态。客户端收到了服务器端确认通知后,此时客户端就会进入到终止状态,等待服务器端发送释放报文。
第三次挥手:服务女器端最后数据发送完毕之后,就像客户端发送连接释放报文,FIN =1,ACK =u+1,当前为半关闭状态,随机生成一个随机数w.
第四次挥手:客户端必须发出确认,ACK = 1,ack = w+1,而自己的序列号是seq = u+1,此时,客户端就进入TIME-WAIT(时间等待状态),注意此时TCP连接还没有释放,必须经过2msl(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入关闭状态。服务器端只要收到了客户端发出的确认,立即进入closed状态,同样,撤销tcp后,就结束了这次的tcp连接,可以看到,服务器结束tcp连接时间要比客户端早一些。
java语言创建Socket应用:
我们来想个场景:比如今天西门大官人突然想去勾栏院幸会李桂姐,当然,这个得先发个消息问下,桂姐今日在否,当勾栏院李桂姐收到消息后,立马回复,大官人,我今日在的,您随时过来吧。西门大官人比作客户端,勾栏院李桂姐比作服务端,我们用代码实现下:
勾栏院李桂姐比作服务端
public class SockerServer {
public static void main(String[] args) {
//创建Socke对象
try {
ServerSocket serverSocket = new ServerSocket();
//创建我们的Socket监听连接和端口号
SocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(),8080);
//绑定我们的监听地址
serverSocket.bind(address);
//等待西门大官人发送消息
System.out.println("等待西门大官人发送消息,西门大官人是我家头号财主!!!");
Socket accept = serverSocket.accept();
PrintWriter socketOut = new PrintWriter(accept.getOutputStream());
byte buf[] = new byte[1024];
if(accept.getInputStream().read(buf)>0){
System.out.println("勾栏院李桂姐接收到消息:============>>>>>>>>>"+new String(buf));
}
//服务器端响应消息
String sendStr = "今日我在勾栏院的,欢迎大官人过来玩啊";
socketOut.write(sendStr);
socketOut.flush();
//关闭连接
socketOut.close();
accept.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
西门大官人比作客户端
public class SocketTcpClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket();
//创建socket地址
SocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(),8080);
socket.connect(address);
//创建Printwrite
PrintWriter sokectOut = new PrintWriter(socket.getOutputStream());
BufferedReader socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//西门庆问勾栏院李桂姐今日在否
String sendStr = "西门庆问桂姐今日在否,我想你了,桂姐!!!";
sokectOut.write(sendStr);
sokectOut.flush();
String receiveStr = socketIn.readLine();
System.out.println("勾栏院李桂姐回复:===================>>>>>>>>>>"+receiveStr);
//关闭连接
socket.close();
socketIn.close();
socket.close();
}
}
Http协议是一种超文本传输协议,基于Tcp/ip协议实现的包装
Http协议默认端口号是80
Https协议443
Https比Http协议安全 ssl + 证书实现传输。传输数据更加安全
长连接与短链接:
这个还要从Http协议版本说起:
Http协议版本分为1.0和2.0,
那么之间最大的区别是什么了,
最大的区别在于客户端与服务器端请求完之后不会立马关闭连接,现在用的都是Http2.0,因为2.0不会频繁的创建和关闭连接,效率来说,相对更高点,目前=都用的是Http1.1的协议:
我们现在就来说说 长连接:客户端与服务器端建立连接之后,不会立马关闭连接,会保持一定的复用机制,当然这也是有一定的实效的,不可能永远不会关闭连接,默认亲况下是300s,空闲情况下会自动断开连接。
短链接:客户端与服务端发送完消息之后,立马关闭连接。如果频繁发送Http请求,可能会消耗服务器的资源。