应swoole长链接开发调研相关TCP知识并记录。php
如图,若是我须要发送一条数据给用户,实际的大小确定是大于你发送的大小,在各个数据层都进行了数据的封包,以便你的数据能完整的发给你想要的用户。html
以太网的数据包的负载是1500字节,IP包头须要20个字节,TCP的包头须要20个字节,实际的数据内容大小则是1460个字节,如图:react
应用层:nginx
如nginx、swoole等,大部分的数据都只须要关心应用层便可,我须要传输什么数据,我只须要调用对应的方法、发送给已知的IP、端口便可。git
TCP层:算法
对应用层的数据进行包装,TCP的报文格式以下图,TCP/UDP层规定了数据的交换格式,如何进行握手、连接,若是加快数据传输、保证数据的完整性等。缓存
TCP层主要有几个算法能够关注下:swoole
慢启动、拥塞避免、快速重传、快恢复、滑动窗口网络
IP层:tcp
细心的人也许已经发现TCP报文格式只有你发送的源端口和目标端口,并无要发送的IP地址和你的IP地址,这些其实都封包在IP层
数据链路层:
数据转换为frame(帧)进行数据传输,为终端通讯提供传输媒体和连接,经常使用设备有网卡、交换机等
物理层:
传输比特流,物理设备传输的层,属于硬件领域范畴,如光纤设备
Wireshark抓的某个包截图:
1、端口号:用来标识同一台计算机的不一样的应用进程。
1)源端口:源端口和IP地址的做用是标识报文的返回地址。
2)目的端口:端口指明接收方计算机上的应用程序接口。
TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP惟一肯定一条TCP链接。
2、序号和确认号:是TCP可靠传输的关键部分。序号是本报文段发送的数据组的第一个字节的序号。在TCP传送的流中,每个字节一个序号。e.g.一个报文段的序号为300,此报文段数据部分共有100字节,则下一个报文段的序号为400。因此序号确保了TCP传输的有序性。确认号,即ACK,指明下一个期待收到的字节序号,代表该序号以前的全部数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。好比创建链接时,SYN报文的ACK标志位为0。
3、数据偏移/首部长度:4bits。因为首部可能含有可选项内容,所以TCP报头的长度是不肯定的,报头不包含任何任选字段则长度为20字节,4位首部长度字段所能表示的最大值为1111,转化为10进制为15,15*32/8 = 60,故报头最大长度为60字节。首部长度也叫数据偏移,是由于首部长度实际上指示了数据区在报文段中的起始偏移值。
4、保留:为未来定义新的用途保留,如今通常置0。
5、控制位:URG ACK PSH RST SYN FIN,共6个,每个标志位表示一个控制功能。
1)URG:紧急指针标志,为1时表示紧急指针有效,为0则忽略紧急指针。
2)ACK:确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。
3)PSH:push标志,为1表示是带有push标志的数据,指示接收方在接收到该报文段之后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。
4)RST:重置链接标志,用于重置因为主机崩溃或其余缘由而出现错误的链接。或者用于拒绝非法的报文段和拒绝链接请求。
5)SYN:同步序号,用于创建链接过程,在链接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而链接应答捎带一个确认,即SYN=1和ACK=1。
6)FIN:finish标志,用于释放链接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。
6、窗口:滑动窗口大小,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小时一个16bit字段,于是窗口大小最大为65535。
7、校验和:奇偶校验,此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。由发送端计算和存储,并由接收端进行验证。
8、紧急指针:只有当 URG 标志置 1 时紧急指针才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另外一端发送紧急数据的一种方式。
9、选项和填充:最多见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每一个链接方一般都在通讯的第一个报文段(为创建链接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不必定是32位的整数倍,因此要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。
10、数据部分: TCP 报文段中的数据部分是可选的。在一个链接创建和一个链接终止时,双方交换的报文段仅有 TCP 首部。若是一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多状况中,也会发送不带任何数据的报文段。
IP报文是对TCP的数据进行了一次包装,再发送给数据链路层,IP报文格式固定格式为20个字节,如图:
更多协议(IP TCP UDP)的报文格式参考:
http://blog.51cto.com/mmanong/1962353
当第一次进行SYN创建连接的时候,客户端会与服务端进行沟通MSS的大小,通常为1460 Byte,每当有一个报文字段被确认,cwnd就增长一个MSS大小,这样随着网络时间RTT的呈指数级增加,可是也不会一直指数级别增长,会有一个最大值的限制
<?php $server = new swoole_server("::", 9503); $server->on('connect', function ($server, $fd){ echo "connection open: {$fd}\n"; }); $server->on('receive', function ($server, $fd, $reactor_id, $data) { $server->send($fd, "Swoole: {$data}"); $server->close($fd); }); $server->on('close', function ($server, $fd) { echo "connection close: {$fd}\n"; }); $server->start();
客户端发送数据后进行抓包,如图:
统计-流量图-显示过滤器的限制,选择TCP Flows:
从结果能够看到tcp从SYN、ACK、FIN的整个过程及每一个过程的耗时状况。
一、 TCP一次数据包发送数据大小不能超过MMS设置,通常为1460字节
二、 TCP慢启动特性在初始传输数据的时候并非直接发送1460数据,而经过慢启动算法指数递增,算法自己不支持进行参数改动
《TCP协议简介》 http://www.ruanyifeng.com/blog/2017/06/tcp-protocol.html
《TCP拥塞控制慢启动窗口设置》 https://blog.csdn.net/lishanmin11/article/details/77186820
《C语言setsockopt函数》 http://c.biancheng.net/cpp/html/374.html
《wireshark使用帮助》 http://www.cnblogs.com/dragonir/p/6219541.html
《网络基本功系列文章》 https://wizardforcel.gitbooks.io/network-basic/content/7.html