1. 程式人生 > >用php模擬做服務端偵聽埠

用php模擬做服務端偵聽埠

參考:http://www.cnblogs.com/thinksasa/archive/2013/02/26/2934206.html

http://blog.csdn.net/alongken2005/article/details/8056910

socket_accept()是服務端接受客戶端請求,一旦有一個客戶端連結上來的話,則這個函式會返回一個新的socket資源,這個資源是與客戶端通訊的資源。

 socket_accept()是阻塞的,會一直卡在那裡。

發現情況:一旦客戶端斷開連結了,會影響到服務端的主程序。如何避免這個影響呢?

正常的伺服器,應該是新開一個子程序來處理請求。

socket_connect()是連結一個socket去。是客戶端使用的。

c語言的介紹:connect, send, recv都是同步阻塞工作模式。

 那麼,可以得出結論,socket_connect()也是阻塞性的。

php中使用協程:

http://www.laruence.com/2015/05/28/3038.html

socket_recv和socket_read($msgsock, 2048, PHP_NORMAL_READ)

有什麼區別呢?

stream_select()

接受一個socket流,可以多個,一個數組形式。

等待這些流改變了狀態。改變了狀態,則會返回大於0的一個值



<?php
/* Prepare the read array */
$read   = array($stream1, $stream2);//建立的兩個socket
$write  = NULL;
$except = NULL;
if (false === ($num_changed_streams = stream_select($read, $write, $except, 0))) {
    /* Error handling */
} elseif ($num_changed_streams > 0) {
    /* At least on one of the streams something interesting happened */
}
?>


要使用引用傳遞,值會被修改。

php多路複用參考資料:http://blog.csdn.net/phphot/article/details/2020269

總結


如果沒有安裝socket擴充套件,則使用如下相關函式:stream_socket_client、fread()、fwrite()、stream_select()、fclose()

如果安裝了sokcet擴充套件,則可以替換掉擴充套件的函式:

stream_socket_client等價於socket_create()

socket_select()等價於stream_select()

socket_close()等價於fclose()

socket_write()等價於fwrite()

socket_read()等價於fread()

stream_socket_client()實際上是在呼叫linux系統的 connect()函式。

socket_select()、stream_select()都是在呼叫作業系統提供的select()函式。

 思考:stream和socket本質有什麼區別呢?

 不知道,想著去去思考socket_accept和socket_listen()區別,也許就能找到答案了。

我總把socket_accept和socket_listen()進行混淆了。

socket_accept是開始接受客戶端的連結,如果有客戶端連結上來,這個函式會返回一個socket通道的控制代碼,這個控制代碼是專門與客戶端單獨的控制代碼。socket_listen是開始偵聽這個socket通道,只是偵聽,並不是接受客戶端的連線請求。