首頁 >後端開發 >php教程 >如何用PHP實作Socket伺服器

如何用PHP實作Socket伺服器

WBOY
WBOY原創
2016-08-08 09:22:071232瀏覽

本文由碼農網 – 王國峰原創翻譯,轉載請看清文末的轉載要求,歡迎加入技術翻譯小組!

想要建立聊天應用,或甚至是遊戲嗎?那麼,socket伺服器將成為你踏出的第一步。一旦你了解了建立伺服器的基本功能,那麼後續的最佳化步驟就會變得同樣簡單。

socket伺服器的工作方式是這樣的,不間斷地運行以等待客戶端的連接。一旦客戶端連接上了,伺服器就會將它新增到客戶名單中,然後開始等待來自客戶端的訊息。

不要走開,下面是完整的源代碼:

// Set time limit to indefinite execution
set_time_limit (0);

// Set the ip and port we will listen on
$address = 'localhost';
$port = 10000;
$max_clients = 10;

// Array that will hold client information
$client = Array();

// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
// Bind the socket to an address/port
socket_bind($sock, $address, $port) or die('Could not bind to address');
// Start listening for connections
socket_listen($sock);

echo "Waiting for connections...\r\n";

// Loop continuously
while (true) {
	// Setup clients listen socket for reading
	$read[0] = $sock;
	for ($i = 0; $i < $max_clients; $i++) {
		if (isset($client[$i]['sock']))
			$read[$i + 1] = $client[$i]['sock'];
	}
	// Set up a blocking call to socket_select()
	if (socket_select($read, $write = NULL, $except = NULL, $tv_sec = 5) < 1)
		continue;
	/* if a new connection is being made add it to the client array */
	if (in_array($sock, $read)) {
		for ($i = 0; $i < $max_clients; $i++) {
			if (empty($client[$i]['sock'])) {
				$client[$i]['sock'] = socket_accept($sock);
				echo "New client connected $i\r\n";
				break;
			}
			elseif ($i == $max_clients - 1)
				echo "Too many clients...\r\n";
		}
	} // end if in_array

	// If a client is trying to write - handle it now
	for ($i = 0; $i < $max_clients; $i++) { // for each client
		if (isset($client[$i]['sock'])) {
			if (in_array($client[$i]['sock'], $read)) {
				$input = socket_read($client[$i]['sock'], 1024);
				if ($input == null) {
					echo "Client disconnecting $i\r\n";
					// Zero length string meaning disconnected
					unset($client[$i]);
				} else {
					echo "New input received $i\r\n";
					// send it to the other clients
					for ($j = 0; $j < $max_clients; $j++) {
						if (isset($client[$j]['sock']) && $j != $i) {
							echo "Writing '$input' to client $j\r\n";
							socket_write($client[$j]['sock'], $input, strlen($input));
						}
					}
					if ($input == 'exit') {
						// requested disconnect
						socket_close($client[$i]['sock']);
					}
				}
			} else {
				echo "Client disconnected $i\r\n";
				// Close the socket
				socket_close($client[$i]['sock']);
				unset($client[$i]);
			}
		}
	}
} // end while
// Close the master sockets
socket_close($sock);

啊呀,乍一看這似乎是一個大工程,但是我們可以先將它分解為幾個較小的部分。第一部分是創建伺服器。 Lines:2至20。

這部分程式碼設定了變數、位址、連接埠、最大客戶端和客戶端陣列。接下來建立socket並將其綁定到我們指定的位址和連接埠上。

下面我們要做的事情就是執行一個死循環(實際上我們是故意的!)。 Lines:22至32。在這部分程式碼中我們做的第一步是設定 $read 陣列。此陣列包含所有客戶端的套接字和我們主伺服器的套接字。這個變數稍後會用於select語句:告訴PHP監聽來自這些客戶端的每一則訊息。

socket_select()的最後一個參數告訴我們的伺服器在回傳值之前最多等待5秒鐘。如果它的回傳值小於1,那麼就表示沒有收到任何數據,所以只需要回到循環頂部,繼續等待。

腳本的下一個部分,是增加新的客戶端到陣列中。 Lines:33至44。

將新的客戶端放置在清單的末尾。檢查以確保客戶端的數量沒有超過我們想要伺服器處理的數量。

下面要介紹的程式碼區塊相當大,也是伺服器的主要部分。當客戶端將訊息傳送到伺服器時,就需要這塊程式碼挺身而出處理。訊息可以是各種各樣的,斷開訊息、實際斷開——只要是伺服器需要處理的訊息。 Lines:46至末。

程式碼循環通過每個客戶端並檢查是否收到來自於它們的訊息。如果是,取得輸入的內容。根據輸入來檢查這是否是一個斷開訊息,如果是那就從數組中刪除它們,反之,那它就是一個正常的消息,那我們的伺服器再次通過所有客戶端,並一個一個寫訊息給他們,跳過發送者。

好了,下面試試看創造自己的聊天伺服器吧!

以上就介紹如何用PHP實作Socket伺服器,包含了方面的內容,希望對PHP教學有興趣的朋友有幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn