Cet article utilise du code PHP pour tester un processus de communication de la couche de transport TCP.
Protocole TCP/IP
Vous pouvez vérifier les détails de ce protocole en vous-même< ;
Le contenu de l'API tcp/udp de PHP est le contenu du manuel PHP
Version PHP testée
Établissement et état de fermeture de la connexion TCP et processus de communication de transmission de données
Code PHP[Ceci est un exemple dans le manuel]
<?php /** * Created by PhpStorm. * User: 1655664358@qq.com * Date: 2019/6/19 * Time: 9:55 */ error_reporting(E_ALL); /* Allow the script to hang around waiting for connections. */ set_time_limit(0); /* Turn on implicit output flushing so we see what we're getting * as it comes in. */ ob_implicit_flush(); $address = '0.0.0.0'; //要监听的ip地址 $port = 54321;//要监听的端口 //创建一个socket AF_INET是一个协议族 (一般都有AF_INET,AF_INET6,AF_UNIX c语言提供也是,只不过是地址族),而PHP叫网络协议 //C语言提供的协议族是PF_INET,PF_INET6,PF_UNIX //SOCK_STREAM sock的服务类型 这里是字节流的服务类型用于TCP if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) { echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; } //socket选项 ,选项一般在socket创建后设置 用于设置TCP的连接属性 //选项几乎和c差不多一样 //一般来说这些选项我们可以通过修改系统内核来调整 if (!socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1)) { echo 'Unable to set option on socket: '. socket_strerror(socket_last_error()) . PHP_EOL; } if (!socket_set_option($sock, SOL_SOCKET, SO_REUSEPORT, 1)) { echo 'Unable to set option on socket: '. socket_strerror(socket_last_error()) . PHP_EOL; } //绑定【有的叫命名socket】 if (socket_bind($sock, $address, $port) === false) { echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; } //监听 此时服务器进入 LISTEN状态 if (socket_listen($sock, 5) === false) { echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; } do { //接受客户端连接sock 从系统内核接受队列里取 如果取出则双方进入了ESTABLISHED状态 if (($msgsock = socket_accept($sock)) === false) { echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; break; } /* Send instructions. */ $msg = "\nWelcome to the PHP Test Server. \n" . "To quit, type 'quit'. To shut down the server type 'shutdown'.\n"; socket_write($msgsock, $msg, strlen($msg)); do { //读客户端数据【从TCP接收接受缓冲区取】 if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) { echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n"; break 2; } if (!$buf = trim($buf)) { continue; } if ($buf == 'quit') { break; } if ($buf == 'shutdown') { //发送FIN结束报文,正常情况服务器会进入CLOSED状态 socket_close($msgsock); break 2; } $talkback = "PHP: You said '$buf'.\n"; socket_write($msgsock, $talkback, strlen($talkback)); echo "$buf\n"; } while (true); socket_close($msgsock); } while (true); socket_close($sock);
Type de service de socket
Fichier d'options TCP/IP
Ensuite, nous démarrons le service
Commande de visualisation de l'état du service : netstat -ntlapc
L'état peut être actualisé toutes les secondes
Outil tcpdump :
tcpdump -A -XX -i lo
Client nous utilisons l'outil Just connect telent et testons
L'image du test est la suivante
Schéma de connexion et d'arrêt
Si l'arrêt est initié par le client, l'état est :
Le client envoie d'abord un paquet FIN de message de fin. À ce moment, il est dans l'état FIN_WAIT1. Le serveur confirme que la réponse est dans l'état CLOSE_WAIT. >À ce moment, le client est dans l'état FIN_WAIT2. Lorsque le serveur envoie également un FIN. À la fin du message, le serveur est dans l'état LAST_LOCK. Après confirmation du client, il est dans l'état TIME_WAIT. Le serveur est fermé.
Diagramme de transition d'état
Peu importe que vous utilisiez l'API SOCKET fournie par PHP ou SWOOLE ou le test écrit en C c'est pareil !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!