原文http://blog.csdn.net/shagoo/article/details/6396089
[root@localhost php]# vi server_one.php
<?php
set_time_limit(0);
class SocketServer
{
private static $socket;
public function __construct($port)
{
global $errno, $errstr;
if ($port < 1024) {
die("Port must be a number which bigger than 1024/n");
} $socket = stream_socket_server("tcp://0.0.0.0:{$port}", $errno, $errstr);
if (!$socket) die("$errstr ($errno)");
//stream_set_timeout($socket, -1); // 保证服务端 socket 不会超时,似乎没用:)
while ($conn = stream_socket_accept($socket, -1)) { // 这样设置不超时才油用 同意一个连接过来并且返回对方的socket套接字
static $id = 0;
static $ct = 0;
$ct_last = $ct;
$ct_data = '';
$buffer = '';
$id++; // increase on each accept
echo "Client $id come./n";
while (!preg_match('/(\/r)?\/n/', $buffer)) { // 没有读到结束符,继续读
// if (feof($conn)) break; // 防止 popen 和 fread 的 bug 导致的死循环
$buffer = fread($conn, 1024);
echo 'R'.PHP_EOL; // 打印读的次数
$ct += strlen($buffer);
$ct_data .= preg_replace('/\/r?\/n/', '', $buffer);
} $ct_size = ($ct - $ct_last) * 8;
echo "[$id] " . __METHOD__ . " > " . $ct_data . "/n".PHP_EOL;
fwrite($conn, "Received 我是服务器我刚接收到你发的数据了大小为 $ct_size byte data ". "/r/n");
echo '那个连上我的人我给你写回复了';
fclose($conn);
} fclose($socket);
}
}
$a = new SocketServer(2000); [root@localhost php]#php server_one.php [root@localhost php]# vi client_one.php
<?php
function debug ($msg)
{
echo $msg;
error_log($msg."\r\n", 3, '/tmp/tmp_socket.log');
} if ($argv[1])
{
$socket_client = stream_socket_client('tcp://0.0.0.0:2000', $errno, $errstr, 30);
stream_set_blocking($socket_client, 0); // 如果模式是0,给定流将转向非阻塞模式 1 阻塞模式
stream_set_timeout($socket_client, 0, 100000); //第二个参数 是否秒的超时设置 第三个参数 时间数 默认微秒 if (!$socket_client) {
die("$errstr ($errno)");
} else {
$msg = trim($argv[1]);
for ($i = 0; $i < 10; $i++) {
$res = fwrite($socket_client, "$msg($i)");
usleep(100000); //以指定的微秒数延迟执行 1微秒(micro second)是百万分之一秒。
echo 'W'; // 打印写的次数
//debug(fread($socket_client, 1024)); //将产生死锁,因为 fread 在阻塞模式下未读到数据时将等待
}
fwrite($socket_client, "/r/n"); // 传输结束符
sleep(2); //注意这里不睡2秒不写日志
debug(fread($socket_client, 10024));
fclose($socket_client);
}
} 开启三个客户端重复如下命令 这时候服务端响应情况 结果只提供一个人的响应服务
[root@localhost php]#telnet 127.0.0.1 2000
crtl + ]
telnet> 直接回车
1
23
234
abc