當前位置:首頁 » 編程語言 » phpstreamsocket

phpstreamsocket

發布時間: 2024-07-07 03:34:50

php socket 如何實現非阻塞

關於socket的阻塞與非阻塞模式以及它們之間的優缺點,這已經沒什麼可言的;我打個很簡單的比方,如果你調用socket send函數時;
如果是阻塞模式下:
send先比較待發送數據的長度len和套接字s的發送緩沖的長度,如果len大於s的發送緩沖區的長度,該函數返回SOCKET_ERROR;如果len小於或者等於s的發送緩沖區的長度,那麼send先檢查協議是否正在發送s的發送緩沖中的數據,如果是就等待協議把數據發送完,如果協議還沒有開始發送s的發送緩沖中的數據或者s的發送緩沖中沒有數據,那麼 send就比較s的發送緩沖區的剩餘空間和len,如果len大於剩餘空間大小,send就一直等待協議把s的發送緩沖中的數據發送完,如果len小於剩餘空間大小send就僅僅把buf中的數據到剩餘空間里
如果是非阻塞模式下:
在調用socket send函數時,如果能寫到socket緩沖區時,就寫數據並返回實際寫的位元組數目,當然這個返回的實際值可能比你所要寫的數據長度要小些(On nonblocking stream oriented sockets, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both the client and server computers),如果不可寫的話,就直接返回SOCKET_ERROR了,所以沒有等待的過程。。
經過上面的介紹後,下面介紹如何設置socket的非阻塞模式:
當使用socket()函數和WSASocket()函數創建套接字時,默認都是阻塞的。在創建套接字之後,通過調用ioctlsocket()函數,將該套接字設置為非阻塞模式。
//-------------------------
// Set the socket I/O mode: In this case FIONBIO
// enables or disables the blocking mode for the
// socket based on the numerical value of iMode.
// If iMode = 0, blocking is enabled;
// If iMode != 0, non-blocking mode is enabled.
u_long iMode = 1; //non-blocking mode is enabled.
ioctlsocket(m_socket, FIONBIO, &iMode); //設置為非阻塞模式

套接字設置為非阻塞模式後,在調用Windows Sockets API函數時,調用函數會立即返回。大多數情況下,這些函數調用都會調用「失敗」,並返回WSAEWOULDBLOCK錯誤代碼。說明請求的操作在調用期間內沒有時間完成。通常,應用程序需要重復調用該函數,直到獲得成功返回代碼。 不同的Windows Sockets API函數,在調用失敗時返回的WSAEWOULDBLOCK錯誤代碼具有不同的含義
需要說明的是並非所有的 Windows Sockets API 在非阻塞模式下調用,都會返回 WSAEWOULDBLOCK 錯誤。例如,以非阻塞模式的套接字為參數調用 bind() 函數時,就不會返回該錯誤代碼。當然,在調用 WSAStartup() 函數時更不會返回該錯誤代碼,因為該函數是應用程序第一調用的函數,當然不會返回這樣的錯誤代碼。
要將套接字設置為非阻塞模式,除了使用 ioctlsocket() 函數之外,還可以使用 WSAAsyncselect() 和 WSAEventselect() 函數。當調用該函數時,套接字會自動地設置為非阻塞方式:

② PHPSocket緙栫▼榪囩▼

PHP錛孲ocket緙栫▼榪囩▼寰堝氫漢榪樹笉鐭ラ亾錛岀幇鍦ㄨ╂垜浠涓璧鋒潵鐪嬬湅鍚э紒
PHP Socket緙栫▼榪囩▼
銆銆Socket鐢ㄤ簬榪涚▼闂撮氫俊錛岃繘紼嬮棿閫氫俊閫氬父鍩轟簬瀹㈡埛絝鈥旀湇鍔$妯″瀷銆傛ゆ椂錛屽㈡埛絝鈥旀湇鍔$鏄鍙浠ュ郊姝や氦浜掔殑搴旂敤紼嬪簭銆傚㈡埛絝鍜屾湇鍔$涔嬮棿鐨勪氦浜掗渶瑕佽繛鎺ャ係ocket緙栫▼璐熻矗鐨勫氨鏄涓哄簲鐢ㄧ▼搴忎箣闂村緩絝嬪彲榪涜屼氦浜掔殑榪炴帴銆備笅闈涓哄ぇ瀹朵粙緇嶄竴涓婸HP Socket緙栫▼榪囩▼!
銆銆浣跨敤浠g爜
銆銆鐩鐨'錛氬紑鍙戜竴涓瀹㈡埛絝鐢ㄤ簬鍙戦乻tring娑堟伅鍒版湇鍔$錛屾湇鍔$灝嗙浉鍚岀殑淇℃伅鍙嶈漿鍚庤繑鍥炵粰瀹㈡埛絝銆
銆銆PHP鏈嶅姟鍣
銆銆絎1姝ワ細璁劇疆鍙橀噺錛屽傗滀富鏈衡濆拰鈥滅鍙b
銆銆$host = "127.0.0.1";$port = 5353;// No Timeout set_time_limit(0);
銆銆絝鍙e彿鍙浠ユ槸1024 -65535涔嬮棿鐨勪換浣曟f暣鏁般
銆銆絎2姝ワ細鍒涘緩socket
銆銆$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socketn");
銆銆絎3姝ワ細緇戝畾socket鍒扮鍙e拰涓繪満
銆銆鍒涘緩鐨剆ocket璧勬簮緇戝畾鍒癐P鍦板潃鍜岀鍙e彿銆
銆銆$result = socket_bind($socket, $host, $port) or die("Could not bind to socketn");
銆銆絎4姝ワ細鍚鍔╯ocket鐩戝惉
銆銆鍦ㄧ粦瀹氬埌IP鍜岀鍙e悗錛屾湇鍔$寮濮嬬瓑寰呭㈡埛絝鐨勮繛鎺ャ傚湪娌℃湁榪炴帴涔嬪墠瀹冨氨涓鐩寸瓑涓嬪幓銆
銆銆$result = socket_listen($socket, 3) or die("Could not set up socket listenern");
銆銆絎5姝ワ細鎺ュ彈榪炴帴
銆銆榪欎釜鍑芥暟浼氭帴鍙楁墍寤虹殑socket浼犲叆鐨勮繛鎺ヨ鋒眰銆傚湪鎺ュ彈鏉ヨ嚜瀹㈡埛絝痵ocket鐨勮繛鎺ュ悗錛岃ュ嚱鏁拌繑鍥炲彟涓涓猻ocket璧勬簮錛屽疄闄呬笂灝辨槸璐熻矗涓庣浉搴旂殑瀹㈡埛絝痵ocket閫氫俊銆傝繖閲岀殑鈥$spawn鈥濆氨鏄璐熻矗涓庡㈡埛絝痵ocket閫氫俊鐨剆ocket璧勬簮銆
銆銆$spawn = socket_accept($socket) or die("Could not accept incoming connectionn");
銆銆鍒扮幇鍦ㄤ負姝錛屾垜浠宸茬粡鍑嗗囧ソ浜嗘湇鍔$痵ocket 錛屼絾瀹為檯涓婅繖涓鑴氭湰騫舵病鏈夊仛浠諱綍浜嬫儏銆傛墍浠ヤ負浜嗙戶緇瀹屾垚涓婅堪鐩鏍囷紝鎴戜滑灝嗚誨彇瀹㈡埛絝痵ocket娑堟伅錛岀劧鍚庡皢鎺ユ敹鍒扮殑娑堟伅鍙嶈漿鍚庡彂鍥炵粰瀹㈡埛絝痵ocket銆
銆銆絎6姝ワ細浠庡㈡埛絝痵ocket璇誨彇娑堟伅
銆銆$input = socket_read($spawn, 1024) or die("Could not read inputn");
銆銆絎7姝ワ細鍙嶈漿娑堟伅
銆銆$output = strrev($input) . "n";
銆銆絎8姝ワ細鍙戦佹秷鎮緇欏㈡埛絝痵ocket
銆銆socket_write($spawn, $output, strlen ($output)) or die("Could not write outputn");
銆銆鍏抽棴socket
銆銆socket_close($spawn);socket_close($socket);
銆銆榪欏氨瀹屾垚浜嗘湇鍔$銆傜幇鍦錛屾垜浠瀛︿範濡備綍鍒涘緩PHP瀹㈡埛絝銆
銆銆PHP瀹㈡埛絝
銆銆鍓嶄袱涓姝ラや笌鏈嶅姟絝鐩稿悓銆
銆銆絎1姝ワ細璁劇疆鍙橀噺錛屽傗滀富鏈衡濆拰鈥滅鍙b
銆銆$host = "127.0.0.1";$port = 5353;// No Timeout set_time_limit(0);
銆銆娉錛氳繖閲岀殑絝鍙e拰涓繪満搴旇ュ拰鏈嶅姟絝涓鐨勫畾涔夋槸鐩稿悓鐨勩
銆銆絎2姝ワ細鍒涘緩socket
銆銆$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socketn");
銆銆絎3姝ワ細榪炴帴鍒版湇鍔$
銆銆$result = socket_connect($socket, $host, $port) or die("Could not connect toservern");
銆銆姝ゆ椂鍜屾湇鍔$涓嶅悓錛屽㈡埛絝痵ocket涓嶇粦瀹氱鍙e拰涓繪満銆傜浉鍙嶏紝瀹冭繛鎺ュ埌鏈嶅姟絝痵ocket錛岀瓑寰呮帴鍙楁潵鑷瀹㈡埛絝痵ocket鐨勮繛鎺ャ傝繖涓姝ュ緩絝嬩簡瀹㈡埛絝痵ocket鍒版湇鍔$痵ocket鐨勮繛鎺ャ
銆銆絎4姝ワ細鍐欏叆鏈嶅姟絝痵ocket
銆銆socket_write($socket, $message, strlen($message)) or die("Could not send data to servern");
銆銆鍦ㄦゆラや腑錛屽㈡埛絝痵ocket鐨勬暟鎹琚鍙戦佸埌鏈嶅姟絝痵ocket銆
銆銆絎5姝ワ細闃呰繪潵鑷鏈嶅姟絝鐨勫搷搴
銆銆$result = socket_read ($socket, 1024) or die("Could not read server responsen");echo "Reply From Server :".$result;
銆銆絎6姝ワ細鍏抽棴socket
銆銆socket_close($socket);
銆銆瀹屾暣鐨勪唬鐮
銆銆鏈嶅姟絝(server.php)
銆銆// set some variables$host = "127.0.0.1";$port = 25003;// don't timeout!set_time_limit(0);// create socket$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socketn");// bind socket to port$result = socket_bind($socket, $host, $port) or die("Could not bind to socketn");// start listening for connections$result = socket_listen($socket, 3) or die("Could not set up socket listenern");// accept incoming connections// spawn another socket to handle communication$spawn = socket_accept($socket) or die("Could not accept incoming connectionn");// read client input$input = socket_read($spawn, 1024) or die("Could not read inputn");// clean up input string$input = trim($input);echo "Client Message : ".$input;// reverse client input and send back$output = strrev($input) . "n";socket_write($spawn, $output, strlen ($output)) or die("Could not write outputn");// close socketssocket_close($spawn);socket_close($socket);
銆銆瀹㈡埛絝(client.php)
銆銆$host = "127.0.0.1";$port = 25003;$message = "Hello Server";echo "Message To server :".$message;// create socket$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socketn");// connect to server$result = socket_connect($socket, $host, $port) or die("Could not connect to servern"); // send string to serversocket_write($socket, $message, strlen($message)) or die("Could not send data to servern");// get server response$result = socket_read ($socket, 1024) or die("Could not read server responsen");echo "Reply From Server :".$result;// close socketsocket_close($socket);
銆銆寤虹珛涓婅堪鏂囦歡(server.php鍜宑lient.php)鍚庯紝鎵ц屽備笅鎿嶄綔錛
銆銆澶嶅埗www鐩褰曚腑鐨勮繖浜涙枃浠(鍋囪網AMP)錛屽畨緗浜嶤:wamp銆
銆銆鎵撳紑Web嫻忚堝櫒錛屽湪鍦板潃鏍忎腑閿鍏localhost 銆
銆銆鍏堟祻瑙坰erver.php鐒跺悗client.php銆

③ 想問下php的socket的工作流程是什麼

PHP 使用Berkley的socket庫來創建它的連接。你可以知道socket只不過是一個數據結構。你使用這個socket數據結構去開始一個客戶端和伺服器之間的會話。這個伺服器是一直在監聽准備產生一個新的會話。當一個客戶端連接伺服器,它就打開伺服器正在進行監聽的一個埠進行會話。這時,伺服器端接受客戶端的連接請求,那麼就進行一次循環。現在這個客戶端就能夠發送信息到伺服器,伺服器也能發送信息給客戶端。
產生一個Socket,你需要三個變數:一個協議、一個socket類型和一個公共協議類型。產生一個socket有三種協議供選擇,繼續看下面的內容來獲取詳細的協議內容。
定義一個公共的協議類型是進行連接一個必不可少的元素。下面的表我們看看有那些公共的協議類型。

表一:協議
名字/常量 描述
AF_INET 這是大多數用來產生socket的協議,使用TCP或UDP來傳輸,用在IPv4的地址
AF_INET6 與上面類似,不過是來用在IPv6的地址
AF_UNIX 本地協議,使用在Unix和Linux系統上,它很少使用,一般都是當客戶端和伺服器在同一台及其上的時候使用
表二:Socket類型
名字/常量 描述
SOCK_STREAM 這個協議是按照順序的、可靠的、數據完整的基於位元組流的連接。這是一個使用最多的socket類型,這個socket是使用TCP來進行傳輸。
SOCK_DGRAM 這個協議是無連接的、固定長度的傳輸調用。該協議是不可靠的,使用UDP來進行它的連接。
SOCK_SEQPACKET 這個協議是雙線路的、可靠的連接,發送固定長度的數據包進行傳輸。必須把這個包完整的接受才能進行讀取。
SOCK_RAW 這個socket類型提供單一的網路訪問,這個socket類型使用ICMP公共協議。(ping、traceroute使用該協議)
SOCK_RDM 這個類型是很少使用的,在大部分的操作系統上沒有實現,它是提供給數據鏈路層使用,不保證數據包的順序

表三:公共協議
名字/常量 描述
ICMP 互聯網控制消息協議,主要使用在網關和主機上,用來檢查網路狀況和報告錯誤信息
UDP 用戶數據報文協議,它是一個無連接,不可靠的傳輸協議
TCP 傳輸控制協議,這是一個使用最多的可靠的公共協議,它能保證數據包能夠到達接受者那兒,如果在傳輸過程中發生錯誤,那麼它將重新發送出錯數據包。

現在你知道了產生一個socket的三個元素,那麼我們就在php中使用socket_create()函數來產生一個socket。這個 socket_create()函數需要三個參數:一個協議、一個socket類型、一個公共協議。socket_create()函數運行成功返回一個包含socket的資源類型,如果沒有成功則返回false。
Resourece socket_create(int protocol, int socketType, int commonProtocol);

現在你產生一個socket,然後呢?php提供了幾個操縱socket的函數。你能夠綁定socket到一個IP,監聽一個socket的通信,接受一個socket;現在我們來看一個例子,了解函數是如何產生、接受和監聽一個socket。

<?php
$commonProtocol = getprotobyname(「tcp」);
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
socket_bind($socket, 『localhost』, 1337);
socket_listen($socket);
// More socket functionality to come
?>

上面這個例子產生一個你自己的伺服器端。例子第一行,
$commonProtocol = getprotobyname(「tcp」);
使用公共協議名字來獲取一個協議類型。在這里使用的是TCP公共協議,如果你想使用UDP或者ICMP協議,那麼你應該把getprotobyname() 函數的參數改為「udp」或「icmp」。還有一個可選的辦法是不使用getprotobyname()函數而是指定SOL_TCP或SOL_UDP在 socket_create()函數中。
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
例子的第二行是產生一個socket並且返回一個socket資源的實例。在你有了一個socket資源的實例以後,你就必須把socket綁定到一個IP地址和某一個埠上。

④ php用STMP郵件發送提示Connection: stream_socket_client not available, falling back to fsockopen

可以檢測下,對外的25埠是否開放,因為stmp服務埠是25

熱點內容
福州雲伺服器找哪家 發布:2024-11-26 12:25:12 瀏覽:84
官服安卓是什麼意思 發布:2024-11-26 12:24:21 瀏覽:528
阿里雲伺服器修改埠 發布:2024-11-26 12:18:21 瀏覽:9
網路存儲器哪個好 發布:2024-11-26 12:03:34 瀏覽:938
crabgame怎麼換伺服器 發布:2024-11-26 12:01:26 瀏覽:250
打開一百兆cad不卡要什麼配置 發布:2024-11-26 11:54:17 瀏覽:616
qq為什麼密碼修改好了就進不去 發布:2024-11-26 11:37:05 瀏覽:383
電容為啥耐壓越大存儲量越小 發布:2024-11-26 11:31:52 瀏覽:190
天然氣車載儲氣瓶泄露處置腳本 發布:2024-11-26 11:17:36 瀏覽:255
換ip的伺服器 發布:2024-11-26 11:17:29 瀏覽:76