首頁  >  文章  >  後端開發  >  TCP 的連線建立與關閉狀態及資料傳輸通訊流程【含 PHP socket API 測試實驗程式碼】

TCP 的連線建立與關閉狀態及資料傳輸通訊流程【含 PHP socket API 測試實驗程式碼】

藏色散人
藏色散人轉載
2019-09-26 09:09:592687瀏覽

本篇文章使用PHP 程式碼來測試TCP 傳輸層的一個通訊過程.

TCP/IP 協定

關於該協定的詳細內容可自行查閱< ;>

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&#39;re getting
 * as it comes in. */
ob_implicit_flush();
$address = &#39;0.0.0.0&#39;;  //要监听的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 &#39;Unable to set option on socket: &#39;. socket_strerror(socket_last_error()) . PHP_EOL;
}
if (!socket_set_option($sock, SOL_SOCKET, SO_REUSEPORT, 1)) {
    echo &#39;Unable to set option on socket: &#39;. 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 &#39;quit&#39;. To shut down the server type &#39;shutdown&#39;.\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 == &#39;quit&#39;) {
            break;
        }
        if ($buf == &#39;shutdown&#39;) {
        //发送FIN结束报文,正常情况服务器会进入CLOSED状态
            socket_close($msgsock);
            break 2;
        }
        $talkback = "PHP: You said &#39;$buf&#39;.\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中文網其他相關文章!

陳述:
本文轉載於:learnku.com。如有侵權,請聯絡admin@php.cn刪除