受到很多引人入胜的标题党的影响,我终于决定,要起一个比他们还标题党的题目,打不过还不能加入吗,嘿嘿。

  网络编程一直是我的弱项,其实归根结底还是我太懒了,一看到那个osi七层模型,TCP/IP模型还有那个来我往的TCP三次握手,四次挥手图,我就头疼,那么多参数,我咋记得住。唉,虽然平时用的少,但是作为逼格小王子,这装逼的基本功还是不能落下。既然记不住,那咋办呢,那就看看他们为啥要这么搞呢,这些层在干嘛,为啥要这么设计呢,接下来咱就一一分析。

  说起网络,咱首先就不得不说计算机网络的体系结构->OSI七层模型和TCP/IP模型:

OSI七层模型:

  百度上的介绍是这样的:参考模型是国际标准化组织(ISO)制定的一个用于计算机通信系统间互联的标准体系,一般称为OSI参考模型或七层模型。这七层分别为:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层。更为详细的这里可以给个链接,我就不抄袭别人的劳动成果了:https://www.cnblogs.com/qishui/p/5428938.html

  但是由于ISO这个组织,逼格太高,设计出的七层模型虽然很牛逼,但是确实在实际使用时,不是那么的接地气,所以由IEEE(电气和电子工程师协会)提出的可行性更高的TCP/IP模型成为了事实上的标准。

TCP/IP模型:

  TCP/IP模型分为应用层(对应osi的应,表,会三层),表传输层,网络层,链路层(对应osi数,物两层),这里我列了一下常见的协议对应关系:

除了链路层可能比较陌生一点,其他的基本上大家都听过,我们用一个可靠的http请求举例:

1.首先会在应用层将这个数据编码并决定建立会话,

2.然后在传输层附加TCP首部(包含序号和重传确认参数),

3.之后在网络层附加IP包(主要包含源ip和目标ip)

4.最后在数据链路层附加以太网首部(主要包含MAC地址),然后通过物理层传输出去

对端接受还是按这个顺序拆包,一一解析。

写到这里估计很多人还是不知道为啥要设计这么多层,我们带着上面的这些步骤来想一下,首先,http请求那必然是需要http协议,对端接收也会按照这个协议来解析,这点很简单,而传输层的TCP三次握手和四次挥手可以保证连接的可靠性,并且TCP这一层会包含序号和重传确认,可以保证对端即使没有顺序接收到请求报,但依然可以按照顺序接受并组装,而TCP包所包含的重传确认可以保证在一定时间内如果没有收到确认回复会再次发一个包,同时序号保证即便多发了包可以将多余的数据丢弃,保证数据的完整性和可靠性。网络层附加的目标ip通过参数路由表找到对端地址,源ip标识请求程序来源,我们经常会用来控制访问白名单限制,最后的链路层MAC地址判断是否发给自己的,若不是则丢弃。

什么是TCP

  TCP是面向连接的通信协议,它通过三次握手建立连接,在传输完成后,需要通过四次挥手解除连接,上面也说到了,TCP会通过重传确认和序号保证数据的完整性和可靠性,同时TCP还可以通过滑动窗口控制每个包的大小,防止发送端发送的数据对端缓存不够大导致数据丢失。TCP还允许通信双方同时进行数据传输,因此我们说TCP是双全工的。

三次握手

  tcp三次握手确实不是很好记,我们做业务的程序员一般也不会接触到这块,但是,理解了tcp三次握手的意义还是很重要的,不过我们还是要先结合图来看一下:

               

                          注:左边这张图是我联想到的便于理解,右边才是正经的三次握手

1.首先客户端会发一个请求,SYN=1,seq=J,SYN=1标识这是一个建立连接请求,seq=J是一个序列号随机数,标识这次请求,然后将客户端置为SYN_SENT状态,

2.之后服务端收到请求,如果没问题就给一个回复吧,ACK=1标识这次请求为应答连接请求,并回复ack=J+1表示当前是对seq=J的回复,并将状态置为SYN_RCVD,同时服务端也要发一个建立连接的请求,和之前意义SYN=1,seq=k , k又是一个随机数, 设计三次握手的大佬呢又觉得你一个人连续发两次有点小孤单,就把两次请求合并在一起了,即上面SYN=1,seq=k;ACK=1,ack=J+1。

3.最后客户端也要回复一下表示我也同意了啊,于是发了一个ACK=1,ack=k+1回去了,并将状态置为ESTABLISHED,服务端收到也将状态置为ESTABLISHED,表示双方建立连接成功了,可以发消息了。其实三次握手和普通请求一样的,就像武林高手过招前要相互试探一下,不怎么花费资源,如果有一方试探的时候嗝屁了,就没有继续比的必要了。我

为什么是三次握手

  回答这个问题之前我们要知道的一件事是三次握手是为了干嘛,其实就是为了确认双方都能友好的建立一个相对稳定连接,就跟相亲一样,男方发一句“你好,约吗”,女方回一句“约啊,在北操场的小树林可以吗”,男方回:“不见不散”,这样才能进行后续的猛烈操作。中间有一个环节断了,就断了。回到正题,客户端发一次请求告诉服务端我要和你建立连接,服务端收到并回复好的,同时也要告诉客户端我要和你建立连接,然后客户端在回复好的,我想最初的模型可能就是和上面左边图一样(那么可能现在就叫四次握手,四次挥手了),不过握手算是将二三次合并为一次,也就是现在的三次握手。为啥三次呢,首先两次肯定是不行的,不能保证双方都建立通信,而目前的逻辑三次已经足够双方建立连接了,也就不需要更多了,资源毕竟是有限的嘛。

四次分手:

  其实三次握手我联想到四次握手也是研究了四次分手之后想到的,我们也来看一下四次分手图,百度上copy过来的,懒得画了:

其实可以对照三次握手来看

1.首先客户端发送FIN断连请求,

2.服务端接收到请求后,判断可以断连则给客户端一个ACK应答

3.服务端发送一个FIN断连请求

4.客户端接收请求后,判断可以断连则给服务端一个ACK应答

相信看懂了三次握手的小伙伴对四次挥手理解起来就很容易了,但是有一个问题,为啥三次握手可以将二三次请求合并为一次,四次挥手咋就不行呢?原因在于客户端发起断连,说明客户端没有数据可以发送了,服务端响应只是表示服务端收到了断连请求,必须要等待服务端数据处理完毕才会发起断连请求,因此,四次挥手是不可以合并的。但三次握手不一样,他不用担心这些问题,毕竟还没开始呢,哪来的数据。

http请求完整过程

  1.首先进行DNS域名解析:

    1.1首先搜索浏览器DNS缓存,搜索不到的话会去操作系统DNS缓存找,找不到去host文件找,最后才会去域名服务器找

  2.三次握手建立TCP连接

  3.客户端正式发起http请求

  4.服务端响应请求

  5.客户端处理资源,如html则解析html代码,有js/css等去请求资源

  6.渲染页面

  7.关闭TCP连接

一般情况短连接到此就结束了,但我们所谓的长连接则会在3-6步骤重复执行,直到需要结束,再关闭TCP连接。

之前在了解http请求的时候,一直在想的一个问题就是:这一个请求如我的博客地址:https://www.cnblogs.com/gmt-hao/p/14502063.html,咋找到对方服务器并被对应程序接受到执行的?

首先https://表示网络中使用的协议是https,而www.cnblogs.com就是我们所说的域名,它会通过域名解析找到对应的ip和端口,ip可以对应找到指定服务器位置,而端口则可以找到当前服务器对应的程序,当然像博客园这样比较大的网站肯定是有网关的,或通过nginx等做路由转发到其他具体的服务器上。/gmt-hao/p/则是我们的虚拟目录,最后根据14502063.html找到目录下对应的资源。

  

总结:

  这篇文章写的还是比较简单的,只是像简单介绍下网络编程的基础,以及我在学习的过程中思考的问题,希望能够帮助到正在学习或者想要学习的小伙伴吧!!!

一文了解网络编程之走进TCP三次握手和HTTP那些你不知道的事的更多相关文章

  1. Linux网络编程——浅谈 TCP 三次握手和四次挥手

    一.tcp协议格式 二.三次握手 在 TCP/IP 协议中.TCP 协议提供可靠的连接服务,採用三次握手建立一个连接. 第一次握手:建立连接时,client发送 syn 包(tcp协议中syn位置1. ...

  2. [转]Linux服务器上11种网络连接状态 和 TCP三次握手/四次挥手详解

    一.Linux服务器上11种网络连接状态: 图:TCP的状态机 通常情况下:一个正常的TCP连接,都会有三个阶段:1.TCP三次握手;2.数据传送;3.TCP四次挥手. 注:以下说明最好能结合”图:T ...

  3. Linux网络编程一、tcp三次握手,四次挥手

    一.TCP报文格式 (图片来源网络) SYN:请求建立连接标志位 ACK:应答标志位 FIN:断开连接标志位 二.三次握手,数据传输,四次挥手 (流程图,图片来源于网络) (tcp状态转换图,图片来源 ...

  4. tcp三次握手四次挥手那些事

    建立TCP需要三次握手才能建立,而断开连接则需要四次挥手.三次握手,四次挥手流程图如下: 一.首先看下如何通过三次挥手----------建立连接 首先客户端发送连接请求报文,服务端接受连接后回复AC ...

  5. Android网络编程系列 一 TCP/IP协议族

    在学习和使用Android网路编程时,我们接触的仅仅是上层协议和接口如Apache的httpclient或者Android自带的httpURlconnection等等.对于这些接口的底层实现我们也有必 ...

  6. 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    .引言 网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一.很多读者都知道“三次”和“四次”,但是如果问深入一点,他们往往都无法作出准确回答. 本篇文章尝试使用动画图片的方 ...

  7. [转帖]脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手   http://www.52im.net/thread-1729-1-1.html     1.引言 网络编程中TCP协议的三次握手和 ...

  8. 网络编程Socket之TCP之close/shutdown具体解释(续)

    接着上一篇网络编程Socket之TCP之close/shutdown具体解释 如今我们看看对于不同情况的close的返回情况和可能遇到的一些问题: 1.默认操作的close 说明:我们已经知道writ ...

  9. Linux网络编程:基于TCP的程序开发回顾篇《转》

    面向连接的TCP程序设计 基于TCP的程序开发分为服务器端和客户端两部分,常见的核心步骤和流程: 其实按照上面这个流程调用系统API确实可以完全实现应用层程序的开发,一点问题没有.可随着时间的推移,你 ...

  10. 用java网络编程中的TCP方式上传文本文件及出现的小问题

    自己今天刚学java网络编程中的TCP传输,要用TCP传输文件时,自己也是遇到了一些问题,抽空把它整理了一下,供自己以后参考使用. 首先在这个程序中,我用一个客户端,一个服务端,从客户端上传一个文本文 ...

随机推荐

  1. centos7安装桌面-GNOME

    CENTOS7安装桌面系统 GNOME桌面 # yum安装 # 更新已安装软件 yum upgrade -y # 安装额外yum源 yum install epel-release -y # 安装X ...

  2. C C++内功心法-基础篇

    大家好,今天给大家讲讲C C++的一些基础语法,小编整理了一些简单入门基础知识,对于我们编程也有很多的帮助. C++ cin C++中的cin是一个 istream对象,从标准输入中读取数据,在ios ...

  3. m1芯片mac安装homebrew

    安装 ARM 版 Homebrew ARM版Homebrew最终被安装在/opt/homebrew路径下. 直接执行: /bin/bash -c "$(curl -fsSL https:// ...

  4. [App Service for Windows]通过 KUDU 查看 Tomcat 配置信息

    问题描述 在App Service 中选择了Java Tomcat后,如何查看Azure App Service的Tomcat的配置信息呢? 问题解答 可以通过以下的 3个步骤查看: 第一步:登录 K ...

  5. 【Azure Redis】Redis导入备份文件(RDB)失败的原因

    问题描述 在测试Azure Redis的导入/导出备份文件的功能中,突然发现在Redis 4.0上导入的时候,一直报错. 问题解答 因为门户上只是显示导入失败,没有任何错误消息说明.根据常理推断,Re ...

  6. 【Azure App Service for Linux】Linux Web App如何安装系统未安装的包

    问题描述 Linux Web App中如何安装系统默认未安装的包,如何来执行如 apt install XXX命令呢?现在遇见的问题时,通过Azure App Service门户中的SSH登录后,执行 ...

  7. 【Azure 存储服务】调用REST API获取Stroage Account Table中所有的Entity计数 -- Count

    问题描述 在Storage Account的使用中,如果想获取Table中全部Entity的计数以及大小,如果是REST API方式,如何来获取呢? 问题解答 在Azure中,所有服务的Metrics ...

  8. [C++逆向] 7 变量在内存中的位置和访问方式

    目录 全局变量和局部变量的区别 局部静态变量 有意思的 堆变量 变量类型 作用域 可访问 全局变量 进程作用域 整个进程可访问 静态变量 文件作用域 当前代码文件可访问 局部变量 函数作用域 函数内可 ...

  9. Java 包装类的使用(自动装箱+自动拆箱)+Vector

    1 package com.bytezreo.ut; 2 3 import java.util.Scanner; 4 import java.util.Vector; 5 6 /** 7 * 8 * ...

  10. 一些网络编程方面的总结,以及redis、memcache、nginx组件的一些介绍

    网络编程主要关注的一些问题 主要关注3个方面的问题 连接的建立 连接的断开 消息的发送和到达 连接的建立 主要分为两种情况:服务器处理接受客户端的连接:服务端作为客户端的连接第三方服务: //这是服务 ...