什么是tcptcp?tcp的定义是七层网络模型中传输层的协议。它由IETF的RFC793定义。它是一种面向连接的、可靠的、基于字节流的通信协议。传输层位于七层模型的中间。下半部分是网络层,上半部分是应用层。地位还是很重要的。传输层还有一个协议udp(connectionless,reliabilitynotguaranteed)。相比之下,tcp具有以下特点:可靠传输、数据丢失、重传机制、数据分段分组传输、控制序列对每个数据号进行流量控制以避免拥塞,因为TCP连接的双方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区能够容纳的数据。tcp数据包格式是按照上图中的结构体划分的,下面进行解释。源端口和目的端口都是16位的,计算机端口标识访问哪个服务。源端口是随机的,目的端口决定收件人。Acceptand因为是16位,所以程序的最大端口号是65535。sequencenumber是发送数据包中第一个字节的sequencenumber。假设当前序号为s,发送数据长度为l,则下一次发送数据时的序号为s+l。当一个连接建立时,通常由计算机产生一个随机数作为序号AcknowledgmentNumber的初始值,它等于下次应该接收的数据的序号。可以认为该位置之前的所有数据都已正常接收。headerlengthTCP报头的长度,单位为4字节。如果没有可选字段,这里的值为5。表示TCP头的长度为20字节(除数据和选项外刚好是20字节)。reservedURG表示UrgentPointer字段有意义ACK表示AcknowledgmentNumber字段有意义PSH表示有DATA数据传输RST表示重置TCP连接SYN表示SYN报文(建立TCP连接时使用)FIN表示没有数据tosend(当TCP关闭连接时使用)Windows表示接收缓冲区的空闲空间,16位,用来告诉TCP连接的另一端可以接收的最大数据长度,流量控制机制是基于这。校验和错误控制,TCP校验和的计算包括TCP头、数据和其他填充字节。发送TCP数据段时,校验和由发送端计算,到达目的地时进行校验和计算。如果两个校验和一致,则数据正确,否则认为数据已损坏,接收端将丢弃该数据。urgent是紧急指针,16位。该字段只有在URG标志置位时才有意义,表示紧急数据相对于序号(SequenceNumber字段的值)的偏移量。tcp三次握手说明上面是我写的一个测试demo,是一个普通的http请求。下面我们抓包分析一下三次tcp握手的细节。第一次握手客户端向服务器发送SYN标志和SequenceNumbers(同步序列号)请求连接,通过它告诉服务器要建立连接,说明第二次握手是服务器使用确认responseACKflag和AcknowledgementNumber告诉客户端数据段已经收到,同时也发送一个syn包(synflag和SequenceNumbers)。说明客户端第三次收到服务器的SYN+ACK报文,向服务器发送确认报文ACK。数据包发送后,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。说明三次握手完成后,链路通道建立成功,下面开始正式的数据传输。对于上面的整个过程,下图将客户端向服务器端发送一个SYN,表示想要建立连接作为三次握手的一部分进行详细的总结。客户端将此连接的序列号设置为随机数c。服务器应该为有效的SYN发回SYN/ACK。ACK的确认码应该是c+1,SYN/ACK包本身有一个随机生成的序号s。最后,客户端发送另一个ACK??。服务器收到这个ACK后,完成三次握手,进入连接创建状态。此时将数据包的序号设置为收到的确认号c+1,响应号为s+1。下面描述四次tcp断开连接的全过程。过程与三次握手机制相同。它还使用一些标志位来实现断开过程。详细步骤没有图解,因为需要四张步骤图,太占篇幅了。下面是根据上面的流程图大致说明一下。客户端发送FIN标志,表示请求断开连接的意思。服务器响应并发送ack标志,表示确认断开连接请求。服务器发送FIN标志,并向相反方向提出关闭请求。客户端发送ack标志,tcp应用场景适用于对数据传输要求比较可靠的地方,比如常见的ftp、http、https、smtp等,这些应用层协议都是基于tcp封装的;而实战中常见的socket编程可以用来开发浏览器通信模块、p2p下载工具等,这些底层都是基于tcp协议的。如何使用tcp协议只是一个规范,实现形式有很多种。具体在node中使用如下形式:letnet=require('net');letpath=require('path');letws=require('fs').createWriteStream(path.join(__dirname,'msg.txt'));letserver=net.createServer(function(socket){socket.pipe(ws,{end:false});});server.听(8080);创建一个tcpserver监听8080端口,将接收到的数据存放在msg.txt文件中。上面的socket是双工流,可以读写。下面是测试的输出来解释上面的只是一个简单的例子,更多的用法可以参考node中的net模块参考链接https://zh.wikipedia.org/wiki...http://nodejs.cn/api/http://www.freebuf.com/专栏...
