php socket 基礎測試

什麼是TCP/IP、UDP?

  TCP/IP(Transmission Control Protocol/Internet Protocol)即傳輸控制協議/網間協議,是一個工業標準的協議集,它是爲廣域網(WANs)設計的。
         UDP(User Data Protocol,用戶數據報協議)是與TCP相對應的協議。它是屬於TCP/IP協議族中的一種。php

TCP與UDP區別:tcp速度慢,安全:udp速度快,不安全.
        這裏有一張圖,代表了這些協議的關係。設計模式

Socket在哪裏呢?

Socket是應用層與TCP/IP協議族通訊的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP /IP協議族隱藏在Socket接口後面,對用戶來講,一組簡單的接口就是所有,讓Socket去組織數據,以符合指定的協議數組

socket 服務端與客戶端工做原理圖

先從服務器端提及。服務器端先初始化Socket,而後與端口綁定(bind),對端口進行監聽(listen),調用accept阻塞,等待客戶端連 接。在這時若是有個客戶端初始化一個Socket,而後鏈接服務器(connect),若是鏈接成功,這時客戶端與服務器端的鏈接就創建了。客戶端發送數 據請求,服務器端接收請求並處理請求,而後把迴應數據發送給客戶端,客戶端讀取數據,最後關閉鏈接,一次交互結束緩存

socket相關函數

socket_accept() 接受一個Socket鏈接
socket_bind() 把socket綁定在一個IP地址和端口上
socket_clear_error() 清除socket的錯誤或者最後的錯誤代碼
socket_close() 關閉一個socket資源
socket_connect() 開始一個socket鏈接
socket_create_listen() 在指定端口打開一個socket監聽
socket_create_pair() 產生一對沒有區別的socket到一個數組裏
socket_create() 產生一個socket,至關於產生一個socket的數據結構
socket_get_option() 獲取socket選項
socket_getpeername() 獲取遠程相似主機的ip地址
socket_getsockname() 獲取本地socket的ip地址
socket_iovec_add() 添加一個新的向量到一個分散/聚合的數組
socket_iovec_alloc() 這個函數建立一個可以發送接收讀寫的iovec數據結構
socket_iovec_delete() 刪除一個已經分配的iovec
socket_iovec_fetch() 返回指定的iovec資源的數據
socket_iovec_free() 釋放一個iovec資源
socket_iovec_set() 設置iovec的數據新值
socket_last_error() 獲取當前socket的最後錯誤代碼
socket_listen() 監聽由指定socket的全部鏈接
socket_read() 讀取指定長度的數據
socket_readv() 讀取從分散/聚合數組過來的數據
socket_recv() 從socket裏結束數據到緩存
socket_recvfrom() 接受數據從指定的socket,若是沒有指定則默認當前socket
socket_recvmsg() 從iovec裏接受消息
socket_select() 多路選擇
socket_send() 這個函數發送數據到已鏈接的socket
socket_sendmsg() 發送消息到socket
socket_sendto() 發送消息到指定地址的socket
socket_set_block() 在socket裏設置爲塊模式
socket_set_nonblock() socket裏設置爲非塊模式
socket_set_option() 設置socket選項
socket_shutdown() 這個函數容許你關閉讀、寫、或者指定的socket
socket_strerror() 返回指定錯誤號的詳細錯誤
socket_write() 寫數據到socket緩存
socket_writev() 寫數據到分散/聚合數組安全

socket服務端與客戶端通訊demo

服務器端:socket.php服務器

<?php
/**
 * Created by IntelliJ IDEA.
 * User: eric
 * Date: 16-8-25
 * Time: 下午5:09
 */
//確保在鏈接客戶端時不會超時
set_time_limit(0);

$ip = '127.0.0.1';
$port = 9527;

/*
 +-------------------------------
 *    @socket通訊整個過程
 +-------------------------------
 *    @socket_create
 *    @socket_bind
 *    @socket_listen
 *    @socket_accept
 *    @socket_read
 *    @socket_write
 *    @socket_close
 +--------------------------------
 */

if(($sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP)) < 0) {
    echo "socket_create() 失敗的緣由是:".socket_strerror($sock)."\n";
}

if(($ret = socket_bind($sock,$ip,$port)) < 0) {
    echo "socket_bind() 失敗的緣由是:".socket_strerror($ret)."\n";
}

if(($ret = socket_listen($sock,4)) < 0) {
    echo "socket_listen() 失敗的緣由是:".socket_strerror($ret)."\n";
}

$count = 0;

do {
    if (($msgsock = socket_accept($sock)) < 0) {
        echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
        break;
    } else {

        //發到客戶端
        $msg ="測試成功!\n";
        socket_write($msgsock, $msg, strlen($msg));

        echo "測試成功了啊\n";
        $buf = socket_read($msgsock,8192);


        $talkback = "收到的信息:$buf\n";
        echo $talkback;

        if(++$count >= 5){
            break;
        };


    }
    //echo $buf;
    socket_close($msgsock);

} while (true);

socket_close($sock);

客戶端:client.php數據結構

<?php
/**
 * Created by IntelliJ IDEA.
 * User: eric
 * Date: 16-8-25
 * Time: 下午5:12
 */
error_reporting(E_ALL);
set_time_limit(0);
echo "<h2>TCP/IP Connection</h2>\n";

$port = 9527;
$ip = "127.0.0.1";

/*
 +-------------------------------
 *    @socket鏈接整個過程
 +-------------------------------
 *    @socket_create
 *    @socket_connect
 *    @socket_write
 *    @socket_read
 *    @socket_close
 +--------------------------------
 */

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket < 0) {
    echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n";
}else {
    echo "OK.\n";
}

echo "試圖鏈接 '$ip' 端口 '$port'...\n";
$result = socket_connect($socket, $ip, $port);
if ($result < 0) {
    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
}else {
    echo "鏈接OK\n";
}

$in = "Ho\r\n";
$in .= "first blood\r\n";
$out = '';

if(!socket_write($socket, $in, strlen($in))) {
    echo "socket_write() failed: reason: " . socket_strerror($socket) . "\n";
}else {
    echo "發送到服務器信息成功!\n";
    echo "發送的內容爲:<font color='red'>$in</font> <br>";
}

while($out = socket_read($socket, 8192)) {
    echo "接收服務器回傳信息成功!\n";
    echo "接受的內容爲:",$out;
}


echo "關閉SOCKET...\n";
socket_close($socket);
echo "關閉OK\n";

先啓動服務端: php socket.phpsocket

運行netstat -ano | grep 9527 能夠查看端口監聽狀況tcp

再執行客戶端: php client.php ,客戶端通訊結果以下:函數

服務端通訊結果以下:

相關文章
相關標籤/搜索