对于初学者,或者没有接触过网络编程的程序员,会以为网络编程涉及的知识很高深,很难,其实这是一种误解,当你的语法熟悉之后,其实基本的网络编程如今已经被实现的异常简单了。前端
网络通讯做为互联网的技术支持,已被普遍应用在软件开发中,不管是Web,服务端,客户端仍是桌面应用,都是必须掌握的一门技术。java
网络编程是什么?
在软件开发层面实现远程数据交换的编程技术。网络编程的本质是两个设备之间的数据交换,固然,在计算机网络中,设备主要指计算机。数据传递自己没有多大的难度,不就是把一个设备中的数据发送给另一个设备,而后接受另一个设备反馈的数据。程序员
OSI参考模型
OSI参考模型,也能够叫作OSI七层模型,在学习网络编程的时候,都会接触到OSI七层模型
,咱们通常使用的网络数据传输由下而上分为七层,这是一个理论的模型。分别是物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
。以下表所示:web
层数 | 名称 | 描述 |
---|---|---|
第七层 | 应用层 | 应用层是 OSI 参考模型的最高层,负责为用户的应用程序提供网络服务。与 OSI 其余层不一样的是,它不为任何其余 OSI 层提供服务,而只是为 OSI 模型之外的应用程序提供服务。包括为相互通讯的应用程序或进行之间创建链接、进行同步,创建关于错误纠正和控 制数据完整性过程的协商等。应用层还包含大量的应用协议,如分布式数据库的访问、文件的交换、电子邮件、虚拟终端等。 |
第六层 | 表示层 | 表示层如下的各层只关心可靠的数据传输,而表示层关心的是所传输数据的语法和语义。它主要涉及处理在两个通讯系统之间所交换信息的表示方式,包括数据格式变换、数据加密与解密、数据压缩与恢复等功能。 |
第五层 | 会话层 | 会话层的功能是在两个节点间创建、维护和释放面向用户的链接。它是在传输链接的基础上创建会话链接,并进行数据交换管理,容许数据进行单工、半双工和全双工的传送。会话层提供了令牌管理和同步两种服务功能。 |
第四层 | 传输层 | 传输层是OSI七层模型中惟一负责端到端节点间数据传输和控制功能的层。传输层是OSI七层模型中承上启下的层,它下面的三层主要面向网络通讯,以确保信息被准确有效地传输;它上面的三个层次则面向用户主机,为用户提供各类服务。传输层经过弥补网络层服务质量的不足,为会话层提供端到端的可靠数据传输服务。它为会话层屏蔽了传输层如下的数据通讯的细节,使会话层不会受到下三层技术变化的影响。但同时,它又依靠下面的三个层次控制实际的网络通讯操做,来完成数据从源到目标的传输。传输层为了向会话层提供可靠的端到端传输服务,也使用了差错控制和流量控制等机制。 |
第三层 | 网络层 | 网络中的两台计算机进行通讯时,中间可能要通过许多中间结点甚至不一样的通讯子网。 网络层的任务就是在通讯子网中选择一条合适的路径,使发送端传输层所传下来的数据能 够经过所选择的路径到达目的端。网络层必须使用寻址方案来肯定存在哪些网络以及设备在这些网络中所处的位置,不一样网络层协议所采用的寻址方案是不一样的。在肯定了目标结点的位置后, 网络层还要负责引导数据包正确地经过网络,找到经过网络的最优路径,即路由选择。若是子网中同时出现过多的分组,它们将相互阻塞通路并可能造成网络瓶颈,因此网络层还须要提供拥塞控制机制以免此类现象的出现。 |
第二层 | 数据链路层 | 数据链路层涉及相邻节点之间的可靠数据传输,数据链路层经过增强物理层传输原始比特的功能,使之对网络层表现为一条无错线路。为了可以实现相邻节点之间无差错的数据传送,数据链路层在数据传输过程当中提供了确认、差错控制和流量控制等机制。 |
第一层 | 物理层 | 物理层位于OSI参考模型的最低层,它直接面向原始比特流的传输。为了实现原始比特流的物理传输,物理层必须解决好包括传输介质、信道类型、数据与信号之间的转换、信号传输中的衰减和噪声等在内的一系列问题。另外,物理层标准要给出关于物理接口的机械、 电气、功能和规程特性,以便于不一样的制造厂家既可以根据公认的标准各自独立地制造设备,又能使各个厂家的产品可以相互兼容。 |
为何OSI要采用分层的形式?由于一个软件逻辑的实现,就是对其进行分层处理。最熟悉不过的就是MVC
,如把后台的代码会分为,数据层,表现层,业务逻辑层,还有如今的先后台分离这种,其实都是分层的一种表现形式,让每一部分的工做都变的跟加的精确和具体。面试
可是在项目中不会像IOS参考模型中那样分层那么细致,比较经常使用的可能就是TCP/IP
协议,那么说到这,什么又是TCP/IP
协议:数据库
TCP/IP
提供点对点的连接机制,将数据应该如何封装、定址、传输、路由以及在目的地如何接收,都加以标准化。它将软件通讯过程抽象化为四个抽象层,采起协议堆栈的方式,分别实现出不一样通讯协议。协议族下的各类协议,依其功能不一样,被分别归属到这四个层次结构之中,常被视为是简化的七层OSI模型
。编程
层数 | 名称 | 涵盖协议 |
---|---|---|
第四层 | 应用层 | TELNET/SSH/HTTP/SMTP/POP/MIB/SIP/HTML(超文本传输协议)... |
第三层 | 传输层 | TCP/UDP/SCTP/DCCP... |
第二层 | 网际层 | ARP/IPv4/ICMP... |
第一层 | 物理层 | 以太网/无线LAN/PPP... |
经过上表中能够看出各个层级所包含的协议,能够把第一层和第二层看做为底层协议,然而在编写软件过程当中不多的时候会用到这两层,由于这辆层通常用到会涉及到物理设备,例如链路、无线这些东西,不多会涉及到软件的逻辑。第三层是在软件开发过程当中比较经常使用的,好比TCP,UDP以后会详细介绍。应用层会更加的熟悉,在作远程登陆,数据传输时会频繁的使用到。浏览器
DNS解析
DNS
解析的过程就是寻找哪台机器上有你须要资源的过程。当你在浏览器中输入一个地址时,例如www.google.com
,其实不是百度网站真正意义上的地址。互联网上每一台计算机的惟一标识是它的IP
地址,可是IP
地址并不方便记忆。用户更喜欢用方便记忆的网址去寻找互联网上的其它计算机,也就是上面提到的百度的网址。因此互联网设计者须要在用户的方便性与可用性方面作一个权衡,这个权衡就是一个网址到IP地址的转换,这个过程就是DNS
解析。它实际上充当了一个翻译的角色,实现了网址到IP
地址的转换。网址到IP
地址转换的过程是如何进行的?缓存
首先在本地域名服务器中查询IP
地址,若是没有找到的状况下,本地域名服务器会向根域名服务器发送一个请求,若是根域名服务器也不存在该域名时,本地域名会向com
顶级域名服务器发送一个请求,依次类推下去。直到最后本地域名服务器获得google
的IP
地址并把它缓存到本地,供下次查询使用。从上述过程当中,能够看出网址的解析是一个从右向左的过程: com -> google.com -> www.google.com
。可是你是否发现少了点什么,根域名服务器的解析过程呢?事实上,真正的网址是www.google.com
.,并非我多打了一个.,这个.对应的就是根域名服务器,默认状况下全部的网址的最后一位都是.,既然是默认状况下,为了方便用户,一般都会省略,浏览器在请求DNS的时候会自动加上,全部网址真正的解析过程为: . -> .com -> google.com. -> www.google.com
。安全
TCP链接
HTTP
协议是使用TCP
做为其传输层协议的,当TCP
出现瓶颈时,HTTP
也会受到影响。我不知道把HTTPS
放在这个部分是否合适,可是放在这里好像又说的过去。HTTP
报文是包裹在TCP
报文中发送的,服务器端收到TCP
报文时会解包提取出HTTP
报文。可是这个过程当中存在必定的风险,HTTP
报文是明文,若是中间被截取的话会存在一些信息泄露的风险。那么在进入TCP
报文以前对HTTP
作一次加密就能够解决这个问题了。HTTPS
协议的本质就是HTTP+SSL(orTLS)
。在HTTP
报文进入TCP
报文以前,先使用SSL
对HTTP
报文进行加密。从网络的层级结构看它位于HTTP
协议与TCP
协议之间。
原理:Net模块提供一个异步API可以建立基于流的TCP服务器,客户端与服务端简历链接后,服务器能够得到一个全双工Socket对象,服务器能够保存Socket对象列表,在接收某客户端消息时,推送给客户端。
dome
服务端:
const net = require("net"); const chatServer = net.createServer(); const clientList = []; chatServer.on("connection",client => { client.write("Hi!\n"); clientList.push(client); client.on("data",data => { console.log("receive:",data.toString()); clientList.forEach(v => { v.write(data); }) }) }); chatServer.listen(9000);
TCP特性
TCP并不能保证数据必定会被对方接收到,由于这是不可能的。TCP可以作到的是,若是有可能,就把数据递送到接收方,不然就(经过放弃重传而且中断链接这一手段)通知用户。所以准确说 TCP 也不是 100% 可靠的协议,它所能提供的是数据的可靠递送或故障的可靠通知。
三次握手与四次挥手
所谓三次握手(Three-way Handshake
),是指创建一个TCP
链接时,须要客户端和服务器总共发送3个包。
三次握手的目的是链接服务器指定端口,创建TCP
链接,并同步链接双方的序列号和确认号,交换 TCP 窗口大小信息。在socket
编程中,客户端执行connect()
时。将触发三次握手。
状态 | 描述 |
---|---|
第一次握手 | 客户端发送一个TCP 的SYN 标志位置1的包,指明客户端打算链接的服务器的端口,以及初始序号X ,保存在包头的序列号(Sequence Number )字段里。 |
第二次握手 | 服务器发回确认包(ACK )应答。即SYN 标志位和ACK 标志位均为1。服务器端选择本身ISN 序列号,放到Seq 域里,同时将确认序号(Acknowledgement Number )设置为客户的ISN 加1,即X+1 。 发送完毕后,服务器端进入SYN_RCVD 状态。 |
第三次握手 | 客户端再次发送确认包(ACK ),SYN 标志位为0,ACK 标志位为1,而且把服务器发来ACK 的序号字段+1,放在肯定字段中发送给对方,而且在数据段放写ISN 的+1。 |
TCP 的链接的拆除须要发送四个包,所以称为四次挥手(Four-way handshake
),也叫作改进的三次握手。客户端或服务器都可主动发起挥手动做,在socket
编程中,任何一方执行close()
操做便可产生挥手操做。
状态 | 描述 |
---|---|
第一次挥手 | 假设客户端想要关闭链接,客户端发送一个FIN 标志位置为1的包,表示本身已经没有数据能够发送了,可是仍然能够接受数据。发送完毕后,客户端进入FIN_WAIT_1 状态。 |
第二次挥手 | 服务器端确认客户端的FIN 包,发送一个确认包,代表本身接受到了客户端关闭链接的请求,但尚未准备好关闭链接。发送完毕后,服务器端进入CLOSE_WAIT 状态,客户端接收到这个确认包以后,进入FIN_WAIT_2 状态,等待服务器端关闭链接。 |
第三次挥手 | 服务器端准备好关闭链接时,向客户端发送结束链接请求,FIN 置为1。发送完毕后,服务器端进入LAST_ACK 状态,等待来自客户端的最后一个ACK 。 |
第四次挥手 | 客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入TIME_WAIT 状态,等待可能出现的要求重传的ACK 包。服务器端接收到这个确认包以后,关闭链接,进入CLOSED 状态。客户端等待了某个固定时间以后,没有收到服务器端的ACK ,认为服务器端已经正常关闭链接,因而本身也关闭链接,进入CLOSED 状态。 |
TCP断开链接时须要四次握手,为何须要4次呢?这是因为TCP半关闭的性质形成的。所谓半关闭,就是能够发送数据,却不能接收数据或只能接收数据,不能发送数据。
HTTP协议
说到这里就是老生常谈的话题了,做为一个前端码农来说,在面试过程当中的是时候这个问题已经被问烂了,基本每次面试都会被问到。
其实这部分又能够称为前端工程师眼中的HTTP
,它主要发生在客户端。发送HTTP
请求的过程就是构建HTTP
请求报文并经过TCP
协议中发送到服务器指定端口(HTTP协议80/8080
,HTTPS协议443
)。HTTP请求报文是由三部分组成: 请求行, 请求报头和请求正文。
特性:
请求报文
HTTP
协议是以ASCII
码传输,创建在TCP/IP
协议之上的应用层规范。规范把HTTP
请求分为三个部分:状态行、请求头、消息主体。
HTTP 定义了与服务器交互的不一样方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE
。URL
全称是资源描述符,咱们能够这样认为:一个URL
地址,它用于描述一个网络上的资源,而 HTTP
中的GET,POST,PUT,DELETE
就对应着对这个资源的查,增,改,删4个操做。
所谓安全的意味着该操做用于获取信息而非修改信息。换句话说,GET
请求通常不该产生反作用。就是说,它仅仅是获取资源信息,就像数据库查询同样,不会修改,增长数据,不会影响资源的状态。
GET方法与POST方法的区别
GET | POST |
---|---|
GET重点在从服务器上获取资源 | POST重点在向服务器发送数据 |
GET传输数据是经过URL请求,以field(字段)= value的形式,置于URL后,并用"?"链接,多个请求数据间用"&"链接 | POST传输数据经过Http的POST机制,将字段与对应值封存在请求实体中发送给服务器,这个过程对用户是不可见的 |
GET传输的数据量小,由于受URL长度限制,但效率较高 | Post能够传输大量数据,因此上传文件时只能用Post方式 |
GET是不安全的,由于URL是可见的,可能会泄露私密信息,如密码等 | POST较GET安全性较高 |
GET方式只能支持ASCII字符,向服务器传的中文字符可能会乱码 | POST支持标准字符集,能够正确传递中文字符 |
总结
网络编程就是使用IP地址,或域名,和端口链接到另外一台计算机上对应的程序,按照规定的协议(数据格式)来交换数据,实际编程中创建链接和发送、接收数据在语言级已经实现,作的更多的工做是设计协议,以及编写生成和解析数据的代码罢了,而后把数据转换成逻辑的结构显示或控制逻辑便可。
对于初学者,或者没有接触过网络编程的程序员,会以为网络编程涉及的知识很高深,很难,其实这是一种误解,当你的语法熟悉之后,其实基本的网络编程如今已经被实现的异常简单了。