Socket 是網絡通信的基礎。PHP 提供 socket_* 系列函數,可構建高效能的 TCP 服務。本文通過一個完整的「回聲服務器」範例,示範如何建立服務端監聽、接受連接、收發數據,以及客戶端連接發送請求的全流程。
SocketServer 類核心步驟:創建 Socket → 綁定 IP/端口 → 監聽 → 循環接受客戶端 → 讀寫數據。
<?php
/**
* 簡易 TCP Socket 服務端
*/
class SocketServer {
private $_port = 9000;
private $_address = '127.0.0.1';
private $_clients = [];
public function __set($name, $val) { $this->$name = $val; }
private function _showError($msg) { exit($msg); }
public function start() {
// 1. 創建 Socket
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($sock === false) $this->_showError("socket_create 失敗: " . socket_strerror(socket_last_error()));
// 2. 綁定地址
if (socket_bind($sock, $this->_address, $this->_port) === false)
$this->_showError("socket_bind 失敗: " . socket_strerror(socket_last_error($sock)));
// 3. 監聽
if (socket_listen($sock, 5) === false)
$this->_showError("socket_listen 失敗: " . socket_strerror(socket_last_error($sock)));
echo "服務已啟動,監聽 {$this->_address}:{$this->_port} ...\n";
// 4. 主循環
while (true) {
$client = socket_accept($sock);
if ($client === false) continue;
$this->_clients[] = $client;
$count = count($this->_clients);
echo "新連接 | 當前連接數: {$count}\n";
// 讀取客戶端數據
$msg = $this->read($client);
echo "收到: {$msg}\n";
// 回覆
$reply = "Server received: {$msg}\n";
$this->send($client, $reply);
// 簡單演示:處理完即關閉(實際項目應維持長連接)
socket_close($client);
$this->_clients = array_diff($this->_clients, [$client]);
}
}
public function send($socket, $data) {
return socket_write($socket, $data, strlen($data));
}
public function read($socket, $len = 8192) {
return socket_read($socket, $len);
}
}
// 啟動服務
$server = new SocketServer();
$server->start();
<?php
$host = '127.0.0.1';
$port = 9000;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) die("創建失敗\n");
if (socket_connect($socket, $host, $port) === false)
die("連接失敗: " . socket_strerror(socket_last_error($socket)) . "\n");
$msg = "Hello from PHP Client at " . date('H:i:s') . "\n";
socket_write($socket, $msg, strlen($msg));
echo "已發送: {$msg}";
$reply = socket_read($socket, 8192);
echo "服務端回覆: {$reply}";
socket_close($socket);
掌握基礎後,可嘗試:
stream_socket_server 簡化代碼。