天天看點

用php模拟做服務端偵聽端口socket_recv和socket_read($msgsock, 2048, PHP_NORMAL_READ)

參考: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

有什麼差別呢?

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通道,隻是偵聽,并不是接受用戶端的連接配接請求。