什么是连接
在网络应用开发中, 程序之间的交互都是通过TCP连接来进行通信的, 比如数据库连接, 事务连接管理。 TCP抽象出来就是一个socket,当我们拥有了这个socket之后,该怎么去使用它呢,这里举几个大家都会的,来通过问题学习知识。
- 比如在数据库连接的时候,如果是并发请求,那数据库的连接是一个并发对应一个连接还是这个连接可以复用给多个并发?
那其实这个问题很多人都知道,一个连接是交给一个并发的,复用的话会发生不可描述的问题(如果复用需要考虑串行话)
- 如果是数据库有事务怎么办?
有事务开启的话是会独占这条连接,不然的话,你在一个连接里提交很多内容会错乱的,它有session的概念,只处理自己的内容。
- 为什么会有threadlocal?
保证自己的操作有专属自己的连接
- 数据库连接里面这个连接是啥连接,怎么连接就ok了?
这个连接就是TCP了,它帮你保证了业务系统之间的数据传输。
- 当APP应用与后端服务器进行通信的时候,连接是复用还是独立的?
当然是独立的。两个并发如果使用一个连接,你发一个我发一个。接收响应时还能区分出来给谁吗?这肯定是不行的。
- HTTP协议连接能不能复用?最终连接数是多少?
不能, 因为必须保证每个请求收到对应的返回结果,如果连接复用,会导致收到的结果不一定就是本次请求对应操作的结果。 最终连接数为65535, 取决于计算机可以开辟的端口数量。
- 连接是啥?
连接在计算机中抽象的表示就是IO
- 两个应用对服务进行通信,可以使用一个连接吗?
其实是可以的,但是必须加锁, 也就是每次只用一个应用获取连接的使用权。不然A应用发送请求, 然后B应用发送请求,这是B应用的请求结果先回来, 而这时候请求被应用A拿到使用, 就会造成期望结果不一致的情况。
OSI 7层网络参考模型
所谓参考模型只是让你参考的,它并没有被设计出来,但也不是没有实现出来,所谓参考模型只是给你做了分层。在计算机的软件工程学当中,分层的目的是为了分层解耦,,也就是层与层之间有固定的接口可以调,,但是层内部的协议和实现可以被替换,
OSI 7层分的有点细,TCP/IP协议基于此被实现了出来,但它把7层的概念简约了,只有应用层、传输控制层、网络层、链路层和物理层,表面上来看就少了一个表示层和会话层。这两个层次一般就是被应用层给整个包含进来了。
真实的应用中并没有7层之多,基本是5层, 其中表示层和会话层不存在了(可以理解为合并到应用层之中了)。
OSI七层模型 | 功能 | 对应的网络协议 | TCP/IP四层概念模型 |
应用层 | 文件传输,文件管理,电子邮件的信息处理——apdu | HTTP、TFTP, FTP, NFS, WAIS、SMTP | 应用层 |
表示层 | 确保一个系统的应用层发送的消息可以被另一个系统的应用层读取,编码转换,数据解析,管理数据的解密和加密,最小单位——ppdu | Telnet, Rlogin, SNMP, Gopher | 应用层 |
会话层 | 负责在网络中的两节点建立,维持和终止通信,在一层协议中,可以解决节点连接的协调和管理问题。包括通信连接的建立,保持会话过程通信连接的畅通,两节点之间的对话,决定通信是否被终端一斤通信终端是决定从何处重新发送,最小单位——spdu | SMTP, DNS | 应用层 |
传输层 | 定义一些传输数据的协议和端口。传输协议同时进行流量控制,或是根据接收方接收数据的快慢程度,规定适当的发送速率,解决传输效率及能力的问题——tpdu | TCP, UDP | 传输层 |
网络层 | 控制子网的运行,如逻辑编址,分组传输,路由选择最小单位——分组(包)报文 | IP, ICMP, ARP, RARP, AKP, UUCP | 网络层 |
数据链路层 | 主要是对物理层传输的比特流包装,检测保证数据传输的可靠性,将物理层接收的数据进行MAC(媒体访问控制)地址的封装和解封装,也可以简单的理解为物理寻址。交换机就处在这一层,最小的传输单位——帧 | FDDI,Ethernet, Arpanet, PDN, SLIP, PPP,STP。HDLC,SDLC,帧中继 | 数据链路层 |
物理层 | 定义物理设备的标准,主要对物理连接方式,电气特性,机械特性等制定统一标准,传输比特流,因此最小的传输单位——位(比特流) | IEEE 802.1A, IEEE 802.2到IEEE 802. | 数据链路层 |
应用层每层其实都自己内部的具体的协议和相应的这个库函数来实现指导具体工作,应用层为什么叫应用层,就是应用application,它是程序员围绕的层次,,在整个通信的过程当中,这个网络层、链路层和物理层向下第几层,都是内核操作内核去实现的。人不用管这个事儿,这剩下几层你不用去开发,,但是作为一个程序员你一定要管什么,你一定管应用层,,你无论是自己创建协议(HTTP、TFTP, FTP, NFS, WAIS、SMTP),不管你使用什么协议,其实这个应用层是由程序员来给它赋能的。
示例演示
nc 连接baidu演示
nc
命令可以完成网络建立连接的过程,就是完成下面这几层(传输层、网络层、数据链路层)。
以连接百度为例nc www.baidu.com 80
一回车,那现在我这台主机就具备了和百度的一个TCP连接,多了一个socket。
(base)[root@VM-0-5-centos ~]# nc www.baidu.com 80
那它建立连接之后,我们和百度应该说什么话,其实这时候就要来到了应用层所要触及的协议,你和百度说什么他能听得懂,就一定受这个协议的约束,你不可能给他发一个STP的或者一个SSh协议的那种报文,他是看不懂的。
可以通过natstat -antp
查看到新建立TCP(socket)的连接
(base) [rootaVM-0-5-centos ~]# netstat -natp Active Internet connections (servers and established) www.bal Om Proto Recv-0 Send-0 Local Address Foreign Address State PID/Program name tcp 日 日 日.日.日.日:22 日.日.日.日:* LISTEN 24896/sshd tcp tcp tcp日日172.17.0.5:220 172.17.0.5:446320 172.17.0.5:45896181.56.9.15:52461106.75.121.230:44106.75.121.236:443 LAST ACK TIME WAIT TIME WAIT tcp 日 日 172.18.0.1:42488 172.18.0.2:3306 TIME WAIT 0 tcp 日 172.17.0.5:60466 180.101.49.11:80 ESTABLISHED 7299/nc tcp 日 0 172.17.0.5:45894 106.75.121 230:443 TIME WAIT tcp日日 172.17.0.5:220 172.17.0.5:45904106.75.121.230:44369.158.207.141:51397 TIME WAIT ESTABLISHED 7465/sshd:unknown tcp tcp 日 日 172.17.0.5:45898 106.75.121.230:443 TIME WAIT tcp tcp日日日 172.17.0.5:22日 172.17.0.5:22121.8.235.37:4311110.87.176.6:5566] ESTABLISHED 7453/sshd: root [pr ESTABLISHED 7016/sshd:root@pts tcp 日 52 172.17.0.5:22 0 172.17.0.5:39614 169 254.0.55:5574 ESTABLISHED 18826/YDService 0 121.8.235.37:4312 ESTABLISHED 7319/sshd:root@pts tcp tcp 日 日 172.17.0.5:45902 106.75.121.230:443 TIME WAIT tcp6 日 日 :::3306 LISTEN 6104/docker-proxy ::;* tcp6 0 :::6379 ::;* LISTEN 28599/docker-proxy 0 tcp6 日 0 ::1:48628 ::1:3306 TIME WAIT (base)[root@VM-0-5-centos ~]#
- local address: 本机ip地址和开启的端口
- foreign address:连接的外部目标的地址和端口
- PID/Program name: 进程ID号和关联的程序名称
- Recv-Q: 读队列
- Send-Q: 写队列
如果想获取网页内容,可以发送通过GET / HTTP/1.0
(基于HTTP协议),如果是其他协议是会报错的,因为人家已经制定好了约束,必须按照规范来
hase)[rontaVM.0-5-centos ~]# nc www.baidu.com 80 GET /HTTP/1.0 请求方式 文件路径 http协议 HTTP/1.0 200 OK Accept-Ranges:bytes Cache-Control:no-cache Content-Length:14615 Content-Type:text/html Date: Mon, 26 0ct 2020 07:11:05 GMT P3p:CP=" OTI DSP COR IVA OUR IND COM " P3p:CP=" OTI DSP COR IVA OUR IND COM Praqma:no-cache n runr
nc 连接redis演示
(base) [root@VM-0-5-centos ~]# nc localhost 6379 keys *$68 spring:session:sessions:expires:e7ed44a9-35b4-4bca-a789-f16d7fa6f9b8$60 spring:session:sessions:e7ed44a9-35b4-4bca-a789-f16d7fa6f9b8$40 spring:session:expirations:1610351040000
(base)[root@VM-0-5-centos ~]# netstat -natp | grep nc tcp6 日 ::1:36366 ::1:6379 ESTABLISHÉD 8679
总结
首先程序APP如果想和外界通讯的话,得先拥有一个连接,给出对方的IP地址和端口号,然后建立连接,得到了一个socket之后,然后从socket里拿到IO才能发东西,,就是才能发你封装协议的字符串。,所以要你的程序第一件事情是要和你的操作系统内核kernel,调用内核当中的一些的系统调用,然后来完成先建立连接,内核里就完成下面这几个层次
应用程序调到传输控制层,传输控制层对于这第一步调的时候做的事情是我想和别人建立连接,因为只有拿到连接才能发东西,应用才能有IO对不对?我想和别人建立连接,那想和别人建立连接的话,这个第一步交给谁了?就是交给了传输控制层。
现在能理解,什么是连接,什么是应用层协议的。这并不重要,重点什么?重点是刚才那个连接,到底怎么建立的?是TCP三次握手吗?肯定啊。