最近在看 workerman,我看的是 3.4.1 版本。整體上大致梳理了一下 workerman 框架的執行流程。當然,我感覺盜用乙個圖說,更容易理解:
相信大家都看的明白,我也就大概說兩句吧,這裡master 程序建立 tcp 伺服器,並啟動 子程序 workers 去接受客戶端的鏈結,處理邏輯。而子程序中,又採用的 epoll 方式,高效的處理連線事件。這裡,我大致,簡易的寫幾個類,放在乙個檔案中,方便大家去理解,workerman 的大致流程。當然,其中還要牽扯很多細節方面的東西,我在此,便不做過多的擴充套件。因為 workerman 已經在這了,寫的很優秀,大家直接看原始碼即可。
1、worker 類
class worker這個類,主要就是 建立 tcp 伺服器,並且監聽 2000 埠。fork 出 4 個子程序,來應對客戶端的鏈結。同時,主程序監聽子程序的動態,有子程序完成任務退出後,立馬補上新的 子程序。/*** fork 子程序
*/public function forkworker()
} /**
* fork 乙個子程序
*/public function forkone()
else if(0 === $pid)
// 新增輪詢 ** 函式
self::$loop->add($this->mainsocket, [$this, 'acceptcb']);
// 啟動事件輪詢
self::$loop->loop();
exit(0);
}else
}/**
* 監管子程序
*/public function monitor()
exit with status $status");
}// 刪除已經退出的子程序id
unset(self::$workers[$pid]);
// 重新 fork 乙個子程序
$this->forkone();
} } }
/*** 接收連線 **
* @param $socket
* @param $flag
* @param $base
*/public function acceptcb($socket, $flag, $base)
/*** 設定當前程序的名稱,在ps aux命令中有用
* 注意 需要php>=5.5或者安裝了protitle擴充套件
* @param string $title
* @return void
*/protected function setprocesstitle($title)
else if (function_exists('cli_set_process_title'))
} }}
2、connetction 類
class connection每乙個客戶端的鏈結,都會例項化乙個 connection 物件來處理這些鏈結。包括讀取客戶端發來的資訊,以及傳送給客戶端一些資訊。/*** 讀取內容**函式
* @param $socket
* @param $flag
* @param $base
*/public function readcb($socket, $flag, $base)
} else
// 向客戶端傳送歡迎資訊
fwrite($socket, "welcome " . (int)$this->_socket);
} /**
* 關閉輪詢
*/public function del()
}
3、libevent 類
class libevent這個類,採用 php libevent 擴充套件,通過 epoll 模式高效的去接收客戶端的請求。/*** 新增事件輪詢
* @param $socket
* @param $func
*/public function add($socket, $func)
/*** 啟動事件輪詢
*/public function loop()
/*** 移除事件輪詢
* @param $socket
*/public function del($socket)
}
測試方法如下 client.php
<?phpworker 類完整 單檔案如下 worker.php/** * author: nickbai
* createtime: 2016/12/17 0017 下午 3:00
*/$socket_client = stream_socket_client('tcp:', $errno, $errstr, 30);
fwrite($socket_client, "hello world!");
sleep(2);
$return = fread($socket_client, 1024);
echo "come from server : " . $return . php_eol;
sleep(2);
fwrite($socket_client, "send again!");
$return = fread($socket_client, 1024);
echo "come from server : " . $return . php_eol;
<?php記住,一定要在 linux 下執行,並且保證你的 php > 5.4 ,以及你安裝了 php libevent 擴充套件 和 pcntl 擴充套件class worker
/*** fork 子程序
*/public function forkworker()
} /**
* fork 乙個子程序
*/public function forkone()
else if(0 === $pid)
// 新增輪詢 ** 函式
self::$loop->add($this->mainsocket, [$this, 'acceptcb']);
// 啟動事件輪詢
self::$loop->loop();
exit(0);
}else
}/**
* 監管子程序
*/public function monitor()
exit with status $status");
}// 刪除已經退出的子程序id
unset(self::$workers[$pid]);
// 重新 fork 乙個子程序
$this->forkone();
} } }
/*** 接收連線 **
* @param $socket
* @param $flag
* @param $base
*/public function acceptcb($socket, $flag, $base)
/*** 設定當前程序的名稱,在ps aux命令中有用
* 注意 需要php>=5.5或者安裝了protitle擴充套件
* @param string $title
* @return void
*/protected function setprocesstitle($title)
else if (function_exists('cli_set_process_title'))
} }}class connection
/*** 讀取內容**函式
* @param $socket
* @param $flag
* @param $base
*/public function readcb($socket, $flag, $base)
} else
// 向客戶端傳送歡迎資訊
fwrite($socket, "welcome " . (int)$this->_socket);
} /**
* 關閉輪詢
*/public function del() }
class libevent
/*** 新增事件輪詢
* @param $socket
* @param $func
*/public function add($socket, $func)
/*** 啟動事件輪詢
*/public function loop()
/*** 移除事件輪詢
* @param $socket
*/public function del($socket) }
new worker();
TCP併發伺服器多程序程式設計
環境 linux c 功能 併發伺服器實現cs通訊 server.c include include include include include include 檔案io read write close fork waitpid include socket struct sockaddr i...
TCP多程序併發伺服器 c
其他關聯文章 丶4ut15m tcp網路程式設計 c udp網路程式設計 c 多執行緒併發伺服器 c io復用 c 多程序併發伺服器整個流程和單程序差別不太大,主要區別在互動部分.伺服器 建立套接字 繫結位址結構 監聽套接字 等待並接受連線請求 主程序建立子程序後執行上一步,子程序與客戶端進行互動 ...
多程序伺服器
基於tcp實現多程序伺服器 伺服器端 1 建立套接字 include include int socket int domain,int type,int protocol domain 乙個位址描述。目前僅支援af inet格式,也就是說arpa internet位址格式。type 指定socke...