欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

TCP 的连接建立与关闭状态及数据传输通信过程【含有 PHP socket API 测试实验代码】

程序员文章站 2022-04-11 10:36:38
...
本文章使用 PHP 代码来测试 TCP 传输层的一个通信过程.

TCP/IP 协议

关于该协议的详细内容可自行查阅 <<TCP/IP 详解 卷 1:协议>>

PHP 的 tcp/udp API 内容是 PHP 手册上的内容

socket API

测试的 PHP 版本

TCP的连接建立与关闭状态及数据传输通信过程

PHP 代码 【就是手册的例子了】

 <?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);

socket 服务类型

TCP 的连接建立与关闭状态及数据传输通信过程【含有 PHP socket API 测试实验代码】

TCP/IP 选项文件

TCP 的连接建立与关闭状态及数据传输通信过程【含有 PHP socket API 测试实验代码】

然后我们启动服务

服务状态查看命令:netstat -ntlapc 可每隔一秒刷新一次状态

tcpdump 工具:

tcpdump -A -XX -i lo

客户端我们使用 telent 工具连接测试 即可

测试图如下

TCP 的连接建立与关闭状态及数据传输通信过程【含有 PHP socket API 测试实验代码】

TCP 的连接建立与关闭状态及数据传输通信过程【含有 PHP socket API 测试实验代码】

TCP 的连接建立与关闭状态及数据传输通信过程【含有 PHP socket API 测试实验代码】

TCP 的连接建立与关闭状态及数据传输通信过程【含有 PHP socket API 测试实验代码】

连接和关闭图

TCP 的连接建立与关闭状态及数据传输通信过程【含有 PHP socket API 测试实验代码】

如果是客户端发起的关闭则状态则是:

客户端先发送一个结束报文 FIN 包,此时处于 FIN_WAIT1 状态,服务器确认应答处于 CLOSE_WAIT 状态

此时客户端处于 FIN_WAIT2 状态,当服务器也发了一次 FIN 结束报文时,服务器处于 LAST_LOCK 状态,客户端确认后处于 TIME_WAIT 状态,服务器则是关闭 CLOSED 了

状态转移图

TCP 的连接建立与关闭状态及数据传输通信过程【含有 PHP socket API 测试实验代码】

不管你用的是 PHP 提供的 SOCKET API 还是 SWOOLE 或是 C 写的测试都一样的!

以上就是TCP 的连接建立与关闭状态及数据传输通信过程【含有 PHP socket API 测试实验代码】的详细内容,更多请关注其它相关文章!

相关标签: PHP