一、TCP/IP协议
TCP/IP协议族按照层次由上到下,层层包装。
第一层应用层,这里面有http,ftp,等等我们熟悉的协议,任务是通过应用进程间的交互来完成特定网路应用。
第二层是传输层,著名的 TCP和UDP协议就在这个层次,为应用进程之间提供端到端的逻辑通信,提供通用的数据传输服务。
第三层是网络层,IP协议就在这里,它负责对数据加上IP地址和其他的数据以确定传输的目标,为主机之间提供逻辑通信。
- IP协议:IP协议是TCP/IP协议的核心,IP的责任是把数据从源传送到目的地,所有的TCP,UDP,IMCP,IGCP的数据都以IP数据格式传输。要注意的是,IP不是可靠的协议,这是说,IP协议没有提供一种数据未传达以后的处理机制--这被认为是上层协议--TCP或UDP要做的事情。所以这也就出现了TCP是一个可靠的协议,而UDP就没有那么可靠的区别
- IP实现两个基本功能:寻址和分段。IP可以根据数据包包头中包括的目的地址将数据报传送到目的地址,在此过程中IP负责选择传送的道路,这种选择道路称为路由功能。
第四层是叫数据链路层,这个层次为待传送的数据加入一个以太网协议头,并进行CRC编码,为最后的数据传输做准备。
- 为IP模块发送和 接收IP数据报。
- 为ARP(地址解析协议)模块发送ARP请求和接收ARP应答。
- 为RARP(逆地址解析协议)发送RARP请 求和接收RARP应答
第五层物理层,负责网络的传输,这个层次的定义包括网线的制式,网卡的定义等等(这些我们就不用关心了,我们也不做网卡),所以有些书并不把这个层次放在tcp/ip协议族里面,因为它几乎和tcp/ip协议的编写者没有任何的关系。发送协议的主机从上自下将数据按照协议封装,而接收数据的主机则按照协议从得到的数据包解开,最后拿到需要的数据。这种结构非常有栈的味道,所以某些文章也把tcp/ip协议族称为tcp/ip协议栈。
一些基本知识:
- 互联网地址(ip地址)
网络上每一个节点都必须有一个独立的Internet地址(也叫做IP地址)。现在,通常使用的IP地址是一个32bit的数字,也就是我 们常说的IPv4标准,这32bit的数字分成四组,也就是常见的255.255.255.255的样式。IPv4标准上,地址被分为五类,我们常用的是 B类地址。具体的分类请参考其他文档。需要注意的是IP地址是网络号+主机号的组合,这非常重要。 - 域名系统
域名系统是一个分布的数据库,它提供将主机名(就是网址啦)转换成IP地址的服务。 - RFC
RFC是什么?RFC就是tcp/ip协议的标准文档。 - 端口号(port)
注意,这个号码是用在TCP,UDP上的一个逻辑号码,并不是一个硬件端口,我们平时说把某某端口封掉了,也只是在IP层次把带有这个号码的IP包给过滤掉了而已。 - 应用编程接口
现在常用的编程接口有socket和TLI。而前面的有时候也叫做“Berkeley socket”,可见Berkeley对于网络的发展有多大的贡献。
物理层:网卡,网线,集线器,中继器,调制解调器
数据链路层:网桥,交换机
网络层:路由器
网关工作在第四层传输层及其以上
交换机就是用来进行报文交换的机器。多为链路层设备(二层交换机),能够进行地址学习,采用存储转发的形式来交换报文.。
路由器的一个作用是连通不同的网络,另一个作用是选择信息传送的线路。选择通畅快捷的近路,能大大提高通信速度,减轻网络系统通信负荷,节约网络系统资源,提高网络系统畅通率。
二、TCP/UDP
TCP:传输控制协议 | 提供面向连接的服务,在传输数据前必须先建立连接,数据传送结束后要释放连接,TCP不提供广播或多播服务,由于TCP要提供可靠的、面向连接的运输服务,因此不可避免地增加了许多的开销,如确认、流量控制、计时器以及连接管理等。只支持点对点通信,全双工 |
UDP:用户数据报协议 | 在传数据前不需要建立连接,远地主机的传输层在收到UDP报文后,不需要给出任何确认,虽然UDP不提供可靠交付,但在某些情况下UDP确是一种最有效的工作方式 支持一对一、一对多、多对多通信 |
应用 | 应用层协议 | 运输层协议 |
名字转换 | DNS(域名系统) | UDP |
IP地址配置 | DHCP(动态主机配置协议) | UDP |
远程文件服务器 | NFS(网络文件系统) | UDP |
IP电话 | 专用协议 | UDP |
电子邮件 | SMTP(简单邮件传输协议) | TCP |
远程终端接入 | TELNET(远程终端协议) | TCP |
万维网 | HTTP(超文本传输协议) | TCP |
文件传送 | FTP(文件传送协议) | TCP |
TCP建立连接过程
首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了(需三次握手)。
断开连接
【注意】中断连接端可以是Client端,也可以是Server端。
假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!
【注意】 在TIME_WAIT状态中,如果TCPclient端最后一次发送的ACK丢失了,它将重新发送。TIME_WAIT状态中所需要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待之后连接正式关闭,并且所有的资源(包括端口号)都被释放。
【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。
【问题3】为什么要三次握手,为什么要向服务器再次发送一次确认呢?
答:这主要是为了防止已失效的连接请求报文段突然又传送到了服务器,因而产生错误。
所谓“失效的连接请求报文段”是这样产生的,考虑一种正常的情况,A发出连接请求,但因为连接请求报文丢失而未收到确认,于是A再重传一次连接请求,后来收到了确认,建立了连接,数据传输完毕后就释放了连接,A共发送两个请求报文段,其中第一个丢失,第二个到达了B,没有“已失效的连接请求报文段”
现假定出现一种异常:A发出的第一个连接请求报文段并没有丢失,而是在某些网络节点长时间滞留了,以致延误到连接释放以后的某个时间才到达B,这是一个早已失效的报文段,但B收到此失效的连接请求报文段后,就误认为是A又发出的一次新的连接请求,于是就向A发出确认报文段,同意建立连接,如果不采取三次握手,那么只要B确认,新的连接就开始了,由于A并没有发出建立请求,就不会理睬B的确认,也不会向B发送数据,B却以为连接开始了,并一直等待A的数据,导致B的资源浪费。
三、Socket
socket连接基于http的三次握手,
服务器监听:服务器端socket并不定位具体的客户端socket,而是处于等待监听状态,实时监控网络状态。
客户端请求:客户端clientSocket发送连接请求,目标是服务器的serverSocket。为此,clientSocket必须知道serverSocket的地址和端口号,进行扫描发出连接请求。
连接确认:当服务器socket监听到或者是受到客户端socket的连接请求时,服务器就响应客户端的请求,建议一个新的socket,把服务器socket发送给客户端,一旦客户端确认连接,则连接建立。
注:在连接确认阶段:服务器socket即使在和一个客户端socket建立连接后,还在处于监听状态,仍然可以接收到其他客户端的连接请求,这也是一对多产生的原因。
下图简单说明连接过程:
异步socket:在服务器端得到这个SOCKET对象以后并不是直接去接收数据而是建立一个回调函数。回调函数是由系统维护的。他在指定的时间自动去扫描数据存储区。假如有数据他就把数据存储到指定的字节数组中。不用用户自己去关心。异步适用于长连接。
<span style="font-size:18px;">发送:
应用程序调用系统调用,将数据发送给socket
socket检查数据类型,调用相应的send函数
send函数检查socket状态、协议类型,传给传输层
tcp/udp(传输层协议)为这些数据创建数据结构,加入协议头部,比如端口号、检验和,传给下层(网络层)
ip(网络层协议)添加ip头,比如ip地址、检验和
如果数据包大小超过了mtu(最大数据包大小),则分片;ip将这些数据包传给链路层
链路层写到网卡队列
网卡调用响应中断驱动程序,发送到网络
接收:
数据包从网络到达网卡,网卡接收帧,放入网卡buffer,在向系统发送中断请求
cpu调用相应中断函数,这些中断处理程序在网卡驱动中
中断处理函数从网卡读入内存,交给链路层
链路层将包放入自己的队列,置软中断标志位
进程调度器看到了标志位,调度相应进程
该进程将包从队列取出,与相应协议匹配,一般为ip协议,再将包传递给该协议接收函数
ip层对包进行错误检测,无错,路由
路由结果,packet被转发或者继续向上层传递
如果发往本机,进入链路层
链路层再进行错误侦测,查找相应端口关联socket,包被放入相应socket接收队列
socket唤醒拥有该socket的进程,进程从系统调用read中返回,将数据拷贝到自己的buffer,返回用户态。</span>
之前总结的,准备找工作了,翻出来晒晒....找工作好累.....累觉不爱......要是现在谁直接给我个offer,劳资直接嫁了。。T T