class socket
{
private $_socket;
private $_domain = AF_INET;
private $_type = SOCK_STREAM;
private $_protocol = SOL_TCP;
private $_clients = [];
private $_max_clients = 10;
public function __construct()
{
if (!extension_loaded('sockets')) {
die('the sockets extension is not loaded!');
}
if (($this->_socket = $this->create($this->_domain, $this->_type, $this->_protocol)) < 0) {
$this->error($this->_socket);
}
}
public function start($ip, $port)
{
if (($res = $this->set_option()) < 0) {
$this->error($res);
}
if (($res = $this->bind($ip, $port)) < 0) {
$this->error($res);
}
if (($res = $this->listen(5)) < 0) {
$this->error($res);
}
#使用非阻塞模式
socket_set_nonblock($this->_socket);
echo "listen on port " . $port . "..." . PHP_EOL;
$clients = array($this->_socket);
while (true) {
$this->_clients = $clients;
$write = [];
$except = [];
if (socket_select($this->_clients, $write, $except, 0) < 1) {
continue;
}
if (in_array($this->_socket, $this->_clients)) {
$clients[] = $connection = $this->connect();
// if (($clients + 1) > $this->_max_clients) {
// echo "Too many clients..." . PHP_EOL;
// } else {
$this->send($connection, "welcome!\nthere are " . (count($clients) - 1) . " client here\n");
socket_getpeername($connection, $client_ip);
echo "new client connected:$client_ip\n";
$key = array_search($connection, $this->_clients);
unset($this->_clients[$key]);
// }
}
foreach($this->_clients as $client){
$receive = $this->receive($client);
if($receive===false){
$key=array_search($client, $clients);
unset($clients[$key]);
echo "client disconnected.\n";
continue;
}
$receive = trim($receive);
if(!empty($receive)){
foreach($clients as $send_socket){
if($send_socket==$this->_socket||$send_socket==$client){
continue;
}
$this->send($send_socket, $this->_socket .">".$client.">"."$receive\n");
}
}
}
}
$this->close();
}
public function bind($ip, $port)
{
socket_bind($this->_socket, $ip, $port);
}
public function listen($max_clients)
{
socket_listen($this->_socket, $max_clients);
}
public function connect()
{
return socket_accept($this->_socket);
}
public function send($connection, $msg)
{
socket_write($connection, $msg);
}
public function receive($client)
{
return socket_read($client, 819292, PHP_NORMAL_READ);
}
public function error($resource)
{
echo socket_strerror($resource) . PHP_EOL;
}
public function close()
{
socket_close($this->_socket);
}
public function create($domain = AF_INET, $type = SOCK_STREAM, $protocol = SOL_TCP)
{
return socket_create($domain, $type, $protocol);
}
public function set_option(){
socket_set_option($this->_socket,SOL_SOCKET,SO_REUSEADDR,1);
}
}
demo
ini_set("display_errors", 1);
include_once INC_PATH . "class/socket.class.php";
$socket = new socket();
$socket->start("192.168.2.113", 1371);