int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);

/*参数列表
int maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错!在Windows中这
个参数的值无所谓,可以设置不正确。
  
fd_set *readfds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的读变化的,
即我们关心是否可以从这些文件中读取数据了,如果这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文
件可读,如果没有可读的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返
回负值。可以传入NULL值,表示不关心任何文件的读变化。
  
fd_set *writefds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的写变化的,
即我们关心是否可以向这些文件中写入数据了,如果这个集合中有一个文件可写,select就会返回一个大于0的值,表示有文
件可写,如果没有可写的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误
返回负值。可以传入NULL值,表示不关心任何文件的写变化。
  
fd_set *errorfds同上面两个参数的意图,用来监视文件错误异常。
  
struct timeval* timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态:
第一,若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描
述符发生变化为止;
第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无
变化返回0,有变化返回一个正值;
第三,timeout的值大于0,这就是等待的超时时间,即 select在timeout时间内阻塞,超时时间之内有事件到来就返回了,
否则在超时后不管怎样一定返回,返回值同上述。
*/
/*
返回值: 
负值:select错误

正值:某些文件可读写或出错

0:等待超时,没有可读写或错误的文件

PHP的socket_select函数也是调用系统的select函数实现的。PHP中socket_select()函数传入的read和write数组是引用传入的,所以每次调用socket_select()后
read和write或者except数组中会包含最新的可以使用的资源数组。传入的是要监视的,而调用socket_select后得到的是可以用的。
http://php.net/manual/zh/function.socket-select.php 服务器端:
 <?php
$port = 1212; $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1); //绑定所有进入该端口的连接
socket_bind($sock, 0, $port); socket_listen($sock); $clients = array($sock); while(true)
{
//socket_select对读写套子节的数字是引用,为了保证clients不被改变,拷贝一份。
$read = $clients;
$write = null;
$expect = null; //当没有套字节可以读写继续等待, 第四个参数为null为阻塞, 为0位非阻塞, 为 >0 为等待时间
if(socket_select($read, $write, $expect, 0) < 1)
{
continue;
} //查看是否有新的连接
if(in_array($sock, $read))
{
$clients[] = $newsock = socket_accept($sock);
socket_write($newsock, 'there are '.(count($clients) - 1)." clients connected\r\n");
socket_getpeername($newsock, $ip);
echo "\nnew client $ip\n";
$key = array_search($sock, $read);
unset($read[$key]);
} //便利所有可读取数据套子节然后广播消息
foreach ($read as $read_sock)
{
$data = @socket_read($read_sock, 1024);
if($data === false)
{
$key = array_search($read_sock, $clients);
socket_getpeername($clients[$key], $ip);
unset($clients[$key]);
echo "client $ip disconnected\n";
continue;
}
$data = trim($data);
if(!empty($data))
{
echo $data;
foreach($clients as $send_sock)
{
if($send_sock == $sock || $send_sock == $read_sock)
{
continue;
}
socket_write($send_sock, $data);
}
}
}
} socket_close($sock);

客户端:

 <?php
set_time_limit(0);
$client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($client, '127.0.0.1', 1212);
socket_write($client, "Form Client client.php \r\n");
while(true)
{
$response = socket_read($client, 1024);
echo $response;
}
socket_close($client);

												

最新文章

  1. Microsoft.Office.Interop.Excel的用法以及利用Microsoft.Office.Interop.Excel将web页面转成PDF
  2. UVA 10004 Bicoloring
  3. NSFileManager文件管理
  4. 十三、mysql 分区之 RANGE &amp;&amp; LIST
  5. 自己编写SqlHelper
  6. DrawingCombiner——CAD图纸批量合并软件
  7. java中遍历map的几种方法介绍
  8. ELF 动态链接 so的动态符号表(.dynsym)
  9. ORACLE透明加密
  10. Java线程池的构造以及使用
  11. NOIP2018复赛获奖分数线及名额分配办法
  12. JAVA设计模式(二)工厂模式
  13. ARP命令详解
  14. sqlserver中怎么查询字段为空的记录
  15. php中empty(),isset(),is_null(),==,===区别
  16. tomcat启动错误:ZipException
  17. spring boot注解学习记
  18. CodeForces 785A Anton and Polyhedrons
  19. 基于jQuery实现文字倾斜显示代码
  20. 一站式机器学习平台TI-ONE是什么?——云+未来峰会开发者专场回顾

热门文章

  1. 【项目】用CIFilter得到图片没办法保存到沙盒里面,显示是CGImage为空
  2. JS左右栏目添加器
  3. Axure7.0汉化方法
  4. accept()
  5. Oracle 的表备份的方法
  6. sudo 出现unable to resolve host 解决方法
  7. JavaScript排序算法——冒泡排序
  8. JavaScript学习笔记——对表单的操作
  9. web页面的加载顺序
  10. FBX Software Development Kit