摘要:所以,它就会将端口号还有一些额外的信息被称作首部,和应用层下发的数据部分进行封装,一起传给下一层即网络层。它们之间的通信,属于同一机器上不同端口号之间的通信。而协议传输的仅仅是无意义的字节流数据,接收方并不能正确读取数据的含义。
baiyan
全部视频:https://segmentfault.com/a/11...
计算机网络架构的分层与封装我们经常谈到,计算机网络有多种体系架构,如OSI七层模型、TCP/IP四层模型等等。那么,为什么要将计算机网络分成这么多层呢?而且,每一层都要加上其特有的头部(如TCP头部、IP头部等等)进行封装,这样设计的原因又何在?
首先我们看一个我们经常看到的C/S架构数据流动过程图:
我们以TCP/IP四层网络体系架构为例,总结一下各层服务的作用:
应用层:用户直接能够操作的层,处理应用程序的逻辑,在用户空间实现
传输层:为两台计算机上的应用程序提供端到端的通信,实现了数据经过网络层到达计算机后能够分发到各个端口(分用),在内核空间实现
网络层:提供精确到两端计算机互联网IP地址的通信,实现了数据包在互联网上的选路与转发,在内核空间实现
数据链路层:提供基于物理媒介(如网卡)的数据传输服务,在内核空间实现
首先谈谈为什么要分层。在我们实际的项目开发过程中,我们常常提到的模块化、服务化,其实和计算机网络为什么要分层的原理类似。我们可以将每一层都看成一个模块、一个服务,其内部的实现细节对于上一层或者下一层都是隐藏的,可能只对外暴露一些API而已。如果上层要使用下层提供的服务,根本不需要关注下一层内部的实现细节,只需使用下层提供的API即可。这样一来,方便了开发与维护,进而提高了计算机网络整体的运作效率。
我们再谈为什么要封装。刚才我们谈到了每个模块都是独立的。上层为了使用下层提供的服务,必须封装。举个例子,应用层想使用传输层提供的端到端的数据传输服务,那么传输层就会将应用层下发的数据先存起来。为了实现端到端的数据传输,传输层模块内部需要标识双方的端口号。所以,它就会将端口号还有一些额外的信息(被称作(TCP/UDP)首部),和应用层下发的数据部分进行封装,一起传给下一层(即网络层)。这样,通过封装每一层特有的头部,实现了每一层独特的功能,最终实现了精确到端口号的端到端数据传输服务。
为什么需要FastCGI协议在LNMP架构中,客户端浏览器与nginx代理是通过HTTP协议进行通信的。在请求到达nginx之后,数据最终会被转发给上游的PHP-FPM。它们之间的通信,属于同一机器上、不同端口号之间的通信。FastCGI协议同HTTP协议一样,是基于TCP协议的,处于TCP协议的上层。而 TCP协议传输的仅仅是无意义的字节流数据,接收方并不能正确读取数据的含义。所以,它们也需要一个类似于HTTP的协议的、一种格式或语法上的规范与约定。这样一来,通信双方才能够更好地理解、解析并正确读取对方传输的信息以及数据,理解数据发送方所表达的含义,这就是FastCGI协议开发的目的所在。
抓包接下来我们会以nginx与PHP-FPM之前通信的数据包为例,利用tcpdump抓取二者通信的数据包。所以我们首先需要了解一下各层数据报头部的格式,但是具体每个字段的作用,我们会在接下来详细讲解,先让我们熟悉一下:
数据链路层(以太网帧为例) 网络层(IPv4协议为例) 传输层(TCP协议为例) 各层之间数据包的联系数据链路层是对网络层数据及头部的封装;
网路层是对传输层数据及头部的封装;
传输层是对应用层数据及头部的封装:
由于FastCGI协议基于TCP协议,那么它一定会进行三次握手与四次挥手,中间的数据包是双方的数据交换,全部的数据包如下:
[root@VM_0_3_centos ~]# tcpdump -i lo port 9000 -S -XX tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes 13:50:43.883490 IP VM_0_3_centos.33844 > VM_0_3_centos.cslistener: Flags [S], seq 608546013, win 43690, options [mss 65495,sackOK,TS val 961901286 ecr 0,nop,wscale 7], length 0 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. 0x0010: 003c de3b 4000 4006 5e7e 7f00 0001 7f00 .<.;@.@.^~...... 0x0020: 0001 8434 2328 2445 acdd 0000 0000 a002 ...4#($E........ 0x0030: aaaa fe30 0000 0204 ffd7 0402 080a 3955 ...0..........9U 0x0040: 72e6 0000 0000 0103 0307 r......... 13:50:43.883520 IP VM_0_3_centos.cslistener > VM_0_3_centos.33844: Flags [S.], seq 2973795481, ack 608546014, win 43690, options [mss 65495,sackOK,TS val 961901286 ecr 961901286,nop,wscale 7], length 0 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. 0x0010: 003c 0000 4000 4006 3cba 7f00 0001 7f00 .<..@.@.<....... 0x0020: 0001 2328 8434 b140 8499 2445 acde a012 ..#(.4.@..$E.... 0x0030: aaaa fe30 0000 0204 ffd7 0402 080a 3955 ...0..........9U 0x0040: 72e6 3955 72e6 0103 0307 r.9Ur..... 13:50:43.883541 IP VM_0_3_centos.33844 > VM_0_3_centos.cslistener: Flags [.], ack 2973795482, win 342, options [nop,nop,TS val 961901286 ecr 961901286], length 0 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. 0x0010: 0034 de3c 4000 4006 5e85 7f00 0001 7f00 .4.<@.@.^....... 0x0020: 0001 8434 2328 2445 acde b140 849a 8010 ...4#($E...@.... 0x0030: 0156 fe28 0000 0101 080a 3955 72e6 3955 .V.(......9Ur.9U 0x0040: 72e6 r. 13:50:43.883594 IP VM_0_3_centos.33844 > VM_0_3_centos.cslistener: Flags [P.], seq 608546014:608546982, ack 2973795482, win 342, options [nop,nop,TS val 961901286 ecr 961901286], length 968 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. 0x0010: 03fc de3d 4000 4006 5abc 7f00 0001 7f00 ...=@.@.Z....... 0x0020: 0001 8434 2328 2445 acde b140 849a 8018 ...4#($E...@.... 0x0030: 0156 01f1 0000 0101 080a 3955 72e6 3955 .V........9Ur.9U 0x0040: 72e6 0101 0001 0008 0000 0001 0000 0000 r............... 0x0050: 0000 0104 0001 03a0 0000 0f35 5343 5249 ...........5SCRI 0x0060: 5054 5f46 494c 454e 414d 452f 6461 7461 PT_FILENAME/data 0x0070: 2f77 7777 2f68 7464 6f63 732f 6461 7461 /www/htdocs/data 0x0080: 2f77 7777 2f68 7464 6f63 732f 736e 6f2f /www/htdocs/sno/ 0x0090: 7075 626c 6963 2f69 6e64 6578 2e70 6870 public/index.php 0x00a0: 0c00 5155 4552 595f 5354 5249 4e47 0e03 ..QUERY_STRING.. 0x00b0: 5245 5155 4553 545f 4d45 5448 4f44 4745 REQUEST_METHODGE 0x00c0: 540c 0043 4f4e 5445 4e54 5f54 5950 450e T..CONTENT_TYPE. 0x00d0: 0043 4f4e 5445 4e54 5f4c 454e 4754 480b .CONTENT_LENGTH. 0x00e0: 0a53 4352 4950 545f 4e41 4d45 2f69 6e64 .SCRIPT_NAME/ind 0x00f0: 6578 2e70 6870 0b01 5245 5155 4553 545f ex.php..REQUEST_ 0x0100: 5552 492f 0c01 444f 4355 4d45 4e54 5f55 URI/..DOCUMENT_U 0x0110: 5249 2f0d 2b44 4f43 554d 454e 545f 524f RI/.+DOCUMENT_RO 0x0120: 4f54 2f64 6174 612f 7777 772f 6874 646f OT/data/www/htdo 0x0130: 6373 2f64 6174 612f 7777 772f 6874 646f cs/data/www/htdo 0x0140: 6373 2f73 6e6f 2f70 7562 6c69 630f 0853 cs/sno/public..S 0x0150: 4552 5645 525f 5052 4f54 4f43 4f4c 4854 ERVER_PROTOCOLHT 0x0160: 5450 2f31 2e31 0e04 5245 5155 4553 545f TP/1.1..REQUEST_ 0x0170: 5343 4845 4d45 6874 7470 1107 4741 5445 SCHEMEhttp..GATE 0x0180: 5741 595f 494e 5445 5246 4143 4543 4749 WAY_INTERFACECGI 0x0190: 2f31 2e31 0f0c 5345 5256 4552 5f53 4f46 /1.1..SERVER_SOF 0x01a0: 5457 4152 456e 6769 6e78 2f31 2e31 312e TWAREnginx/1.11. 0x01b0: 390b 0f52 454d 4f54 455f 4144 4452 3131 9..REMOTE_ADDR11 0x01c0: 332e 3232 372e 3234 392e 3132 370b 0552 3.227.249.127..R 0x01d0: 454d 4f54 455f 504f 5254 3533 3931 330b EMOTE_PORT53913. 0x01e0: 0a53 4552 5645 525f 4144 4452 3137 322e .SERVER_ADDR172. 0x01f0: 3136 2e30 2e33 0b02 5345 5256 4552 5f50 16.0.3..SERVER_P 0x0200: 4f52 5438 300b 0d53 4552 5645 525f 4e41 ORT80..SERVER_NA 0x0210: 4d45 6772 6170 652e 7961 662e 636f 6d0f MEgrape.yaf.com. 0x0220: 0352 4544 4952 4543 545f 5354 4154 5553 .REDIRECT_STATUS 0x0230: 3230 3009 0f48 5454 505f 484f 5354 3132 200..HTTP_HOST12 0x0240: 322e 3135 322e 3232 392e 3232 310f 0a48 2.152.229.221..H 0x0250: 5454 505f 434f 4e4e 4543 5449 4f4e 6b65 TTP_CONNECTIONke 0x0260: 6570 2d61 6c69 7665 1209 4854 5450 5f43 ep-alive..HTTP_C 0x0270: 4143 4845 5f43 4f4e 5452 4f4c 6d61 782d ACHE_CONTROLmax- 0x0280: 6167 653d 301e 0148 5454 505f 5550 4752 age=0..HTTP_UPGR 0x0290: 4144 455f 494e 5345 4355 5245 5f52 4551 ADE_INSECURE_REQ 0x02a0: 5545 5354 5331 0f79 4854 5450 5f55 5345 UESTS1.yHTTP_USE 0x02b0: 525f 4147 454e 544d 6f7a 696c 6c61 2f35 R_AGENTMozilla/5 0x02c0: 2e30 2028 4d61 6369 6e74 6f73 683b 2049 .0.(Macintosh;.I 0x02d0: 6e74 656c 204d 6163 204f 5320 5820 3130 ntel.Mac.OS.X.10 0x02e0: 5f31 355f 3029 2041 7070 6c65 5765 624b _15_0).AppleWebK 0x02f0: 6974 2f35 3337 2e33 3620 284b 4854 4d4c it/537.36.(KHTML 0x0300: 2c20 6c69 6b65 2047 6563 6b6f 2920 4368 ,.like.Gecko).Ch 0x0310: 726f 6d65 2f37 352e 302e 3337 3730 2e31 rome/75.0.3770.1 0x0320: 3030 2053 6166 6172 692f 3533 372e 3336 00.Safari/537.36 0x0330: 0b76 4854 5450 5f41 4343 4550 5474 6578 .vHTTP_ACCEPTtex 0x0340: 742f 6874 6d6c 2c61 7070 6c69 6361 7469 t/html,applicati 0x0350: 6f6e 2f78 6874 6d6c 2b78 6d6c 2c61 7070 on/xhtml+xml,app 0x0360: 6c69 6361 7469 6f6e 2f78 6d6c 3b71 3d30 lication/xml;q=0 0x0370: 2e39 2c69 6d61 6765 2f77 6562 702c 696d .9,image/webp,im 0x0380: 6167 652f 6170 6e67 2c2a 2f2a 3b71 3d30 age/apng,*/*;q=0 0x0390: 2e38 2c61 7070 6c69 6361 7469 6f6e 2f73 .8,application/s 0x03a0: 6967 6e65 642d 6578 6368 616e 6765 3b76 igned-exchange;v 0x03b0: 3d62 3314 0d48 5454 505f 4143 4345 5054 =b3..HTTP_ACCEPT 0x03c0: 5f45 4e43 4f44 494e 4767 7a69 702c 2064 _ENCODINGgzip,.d 0x03d0: 6566 6c61 7465 140e 4854 5450 5f41 4343 eflate..HTTP_ACC 0x03e0: 4550 545f 4c41 4e47 5541 4745 7a68 2d43 EPT_LANGUAGEzh-C 0x03f0: 4e2c 7a68 3b71 3d30 2e39 0104 0001 0000 N,zh;q=0.9...... 0x0400: 0000 0105 0001 0000 0000 .......... 13:50:43.883602 IP VM_0_3_centos.cslistener > VM_0_3_centos.33844: Flags [.], ack 608546982, win 357, options [nop,nop,TS val 961901286 ecr 961901286], length 0 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. 0x0010: 0034 f67c 4000 4006 4645 7f00 0001 7f00 .4.|@.@.FE...... 0x0020: 0001 2328 8434 b140 849a 2445 b0a6 8010 ..#(.4.@..$E.... 0x0030: 0165 fe28 0000 0101 080a 3955 72e6 3955 .e.(......9Ur.9U 0x0040: 72e6 r. 13:50:43.885366 IP VM_0_3_centos.cslistener > VM_0_3_centos.33844: Flags [P.], seq 2973795482:2973795650, ack 608546982, win 357, options [nop,nop,TS val 961901288 ecr 961901286], length 168 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. 0x0010: 00dc f67d 4000 4006 459c 7f00 0001 7f00 ...}@.@.E....... 0x0020: 0001 2328 8434 b140 849a 2445 b0a6 8018 ..#(.4.@..$E.... 0x0030: 0165 fed0 0000 0101 080a 3955 72e8 3955 .e........9Ur.9U 0x0040: 72e6 0106 0001 008d 0300 582d 506f 7765 r.........X-Powe 0x0050: 7265 642d 4279 3a20 5048 502f 372e 322e red-By:.PHP/7.2. 0x0060: 3132 0d0a 436f 6e74 656e 742d 5479 7065 12..Content-Type 0x0070: 3a61 7070 6c69 6361 7469 6f6e 2f6a 736f :application/jso 0x0080: 6e3b 2063 6861 7273 6574 3d75 7466 2d38 n;.charset=utf-8 0x0090: 0d0a 0d0a 7b22 7374 6174 7573 223a 3531 ....{"status":51 0x00a0: 342c 226d 7367 223a 2255 6e65 7863 6570 4,"msg":"Unexcep 0x00b0: 7465 6420 6120 656d 7074 7920 636f 6e74 ted.a.empty.cont 0x00c0: 726f 6c6c 6572 206e 616d 6522 2c22 6461 roller.name","da 0x00d0: 7461 223a 5b5d 7d00 0000 0103 0001 0008 ta":[]}......... 0x00e0: 0000 0000 0000 0077 5c2f .......w/ 13:50:43.885378 IP VM_0_3_centos.33844 > VM_0_3_centos.cslistener: Flags [.], ack 2973795650, win 350, options [nop,nop,TS val 961901288 ecr 961901288], length 0 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. 0x0010: 0034 de3e 4000 4006 5e83 7f00 0001 7f00 .4.>@.@.^....... 0x0020: 0001 8434 2328 2445 b0a6 b140 8542 8010 ...4#($E...@.B.. 0x0030: 015e fe28 0000 0101 080a 3955 72e8 3955 .^.(......9Ur.9U 0x0040: 72e8 r. 13:50:43.885396 IP VM_0_3_centos.cslistener > VM_0_3_centos.33844: Flags [F.], seq 2973795650, ack 608546982, win 357, options [nop,nop,TS val 961901288 ecr 961901288], length 0 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. 0x0010: 0034 f67e 4000 4006 4643 7f00 0001 7f00 .4.~@.@.FC...... 0x0020: 0001 2328 8434 b140 8542 2445 b0a6 8011 ..#(.4.@.B$E.... 0x0030: 0165 fe28 0000 0101 080a 3955 72e8 3955 .e.(......9Ur.9U 0x0040: 72e8 r. 13:50:43.885667 IP VM_0_3_centos.33844 > VM_0_3_centos.cslistener: Flags [F.], seq 608546982, ack 2973795651, win 350, options [nop,nop,TS val 961901288 ecr 961901288], length 0 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. 0x0010: 0034 de3f 4000 4006 5e82 7f00 0001 7f00 .4.?@.@.^....... 0x0020: 0001 8434 2328 2445 b0a6 b140 8543 8011 ...4#($E...@.C.. 0x0030: 015e fe28 0000 0101 080a 3955 72e8 3955 .^.(......9Ur.9U 0x0040: 72e8 r. 13:50:43.885678 IP VM_0_3_centos.cslistener > VM_0_3_centos.33844: Flags [.], ack 608546983, win 357, options [nop,nop,TS val 961901288 ecr 961901288], length 0 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. 0x0010: 0034 f67f 4000 4006 4642 7f00 0001 7f00 .4..@.@.FB...... 0x0020: 0001 2328 8434 b140 8543 2445 b0a7 8010 ..#(.4.@.C$E.... 0x0030: 0165 fe28 0000 0101 080a 3955 72e8 3955 .e.(......9Ur.9U 0x0040: 72e8 r.
我们可以看到,前三个包就是TCP的三次握手,经过了一定量的数据传输之后,最后四个包就是TCP的四次挥手,我们可以用下图来进行表示:
我们挑选第二个数据包进行详细讲解。我们可以分析出,它是建立TCP连接的三次握手中的第二次握手,是由服务端返回给客户端的ACK包:
13:50:43.883520 IP VM_0_3_centos.cslistener > VM_0_3_centos.33844: Flags [S.], seq 2973795481, ack 608546014, win 43690, options [mss 65495,sackOK,TS val 961901286 ecr 961901286,nop,wscale 7], length 0 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. 0x0010: 003c 0000 4000 4006 3cba 7f00 0001 7f00 .<..@.@.<....... 0x0020: 0001 2328 8434 b140 8499 2445 acde a012 ..#(.4.@..$E.... 0x0030: aaaa fe30 0000 0204 ffd7 0402 080a 3955 ...0..........9U 0x0040: 72e6 3955 72e6 0103 0307 r.9Ur.....
每一组是4个16进制数字,所以每一组是16位,即两个字节。
由于当前数据包是经过层层封装的最终的数据包,所以它包含帧头部、IP头部、TCP头部、以及应用程序数据(参考上图)下面我们逐个字节分析:
帧头部0000 0000 0000:源MAC地址(源MAC地址是6个字节,由于都是本机所以为全0)
0000 0000 0000:目的MAC地址(目的MAC地址是6个字节)
0800:表示类型为IP数据报(类型字段为了区分是使用IP协议、ARP协议还是RARP协议类型的帧)
IPv4协议头部4:版本号为IPv4
5:IP协议头部长度为5 * 4(以4B为单位计算) = 20字节
00:8位服务类型
003c:总长度为60字节
0000:16位标识(同一个IP数据报的所有分片的标识均相同)
4000:3位标志 + 13位片偏移(0100 0000 0000 0000)(010代表禁止分片,片偏移为0)
40:8位生存时间TTL(数据报到达目的地之前允许的路由器跳数,通常为64)
06:8位协议(用来区分上层协议,6为TCP)
3cba:16位头部校验和(接收端使用CRC算法检验IP数据报头部是否损坏)
7f00 0001:32位源端IP地址(转化为十进制127.0.0.1)
7f00 0001:32位目的端IP地址(转化为十进制127.0.0.1)
TCP协议头部2328:16位源端口号(十进制值为9000,因为PHP-FPM的端口号为9000)
8434:16位目的端口号(十进制值为33844,是建立初始TCP连接时产生的随机端口号)
b140 8499:32位序号(十进制值为2973795481,是服务端的初始序号)
2445 acde:32位确认号(十进制值为608546014,代表客户端608546013及之前序号的报文段已全部收到)
a:TCP协议头部长度为10 * 4(以4B为单位计算) = 40字节
012:6位保留 + URG|ACK|PSH|RST|SYN|FIN (012 = 000000 010010,即ACK = 1及SYN = 1,符合三次握手规律)
aaaa:16位窗口大小(十进制值为43690,告诉对方自己的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制数据的发送速度)
fe30:16位校验和(接收端使用CRC算法检验TCP数据报头部及数据部分是否损坏,是TCP可靠传输的保障)
0000:16位紧急指针(用来让发送端给接收端发送紧急数据)
0204 ffd7 0402 080a 3955 72e6 3955 72e6 0103 0307:20字节的TCP头部选项
当三次握手之后,TCP连接正式建立。我们可以在下面几个包中看到具体的HTTP协议的请求行、请求主体、以及相应的返回状态码及响应主体等内容。
我们总结一下,FastCGI协议其实就相当于基于TCP协议的HTTP协议。在LNMP架构中,nginx是一个web服务器,只支持HTTP协议数据的输入与输出;而PHP-FPM只支持FastCGI协议的输入与输出,这里nginx就可以看成是一个协议转换器的作用。它下层的TCP协议是面向字节流传输的,传给对方的只是一堆的字节数据,接收方无法解析其内容所代表的含义。那么我们开发HTTP协议、FastCGI协议等等也是同理。为了能够让PHP-FPM更加轻松容易地解析nginx转发过来的数据包,读懂基于TCP的这些字节流数据的含义,那么我们必须约定一种数据格式,让数据的传输、读取更加方便、高效、规范,这就是开发FastCGI协议的目的。这篇文章只是给大家一个复习以及铺垫,具体FastCGI协议所规定的格式与详细内容请听下回分解。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/40519.html
摘要:此文用于汇总跟随陈雷老师及团队的视频,学习源码过程中的思考整理与心得体会,此文会不断更新视频传送门每日学习记录使用录像设备记录每天的学习源码学习源码学习内存管理笔记源码学习内存管理笔记源码学习内存管理笔记源码学习基本变量笔记 此文用于汇总跟随陈雷老师及团队的视频,学习源码过程中的思考、整理与心得体会,此文会不断更新 视频传送门:【每日学习记录】使用录像设备记录每天的学习 PHP7...
摘要:全部视频引入读这篇文章之前请先阅读源码学习协议我们知道,客户端之间通信的方式如下那么,我们今天详细解释一下图中的协议的部分。协议就是为了解决协议的相关问题而出现,是协议的升级版。在配置中指令中指定的值请求使用的协议,通常是或。 baiyan 全部视频:https://segmentfault.com/a/11... 引入 读这篇文章之前请先阅读【PHP源码学习】2019-04-09 ...
摘要:,配是通过一个类似的协议,升级版的的。在上有帮你管理进程,在似乎没有,这是有点令人悲伤的。检验一下然后开启然后配置中里文件在盘建立一个的文件夹,放入,开启测试写入访问应用我的项目就用了这个东西,,欢迎 fastcgi As we all know,nginx配php是通过fastcgi(一个类似http的协议,升级版的cgi)的。在linux上有php-fpm帮你管理进程,在windo...
阅读 3016·2023-04-26 00:32
阅读 498·2019-08-30 15:52
阅读 2104·2019-08-30 15:52
阅读 3346·2019-08-30 15:44
阅读 3279·2019-08-30 14:09
阅读 1415·2019-08-29 15:15
阅读 3389·2019-08-28 18:12
阅读 1073·2019-08-26 13:55