主要代码在下面:

socket_set_nonblock($listensocket);
if(socket_select($rconnections,$wconnections,$econnections=NULL,self::$timeout)>0){
//新连接
if(in_array($listensocket,$rconnections)){
$connection=socket_accept($listensocket);
//超过负载
if(count(self::$connections)>=self::$maxconnections){
$reject="服务器超载了,请稍后再来!\r\n";
socket_write($connection,$reject,strlen($reject));
socket_shutdown($connection,2);
socket_close($connection);
}else{
$i=(int)$connection;
//socket_set_nonblock($connection);
self::$connections[$i]=$connection;
$wconnections[$i]=$connection;
}
//删除监听socket,监听socket包含在可读connections中
unset($rconnections[array_search($listensocket,$rconnections)]);
}
print_r($rconnections);
print_r(self::$connections);
//读
foreach($rconnections as $rconnection){
$data=socket_read($rconnection,1024,PHP_NORMAL_READ);
if($data===false){
echo socket_strerror(socket_last_error());
echo ((int)$rconnection)."断开连接:\r\n";
socket_shutdown($rconnection,2);
socket_close($rconnection);
unset(self::$connections[(int)$rconnection]);
continue;
}
if(!preg_match('/\\r?\\n/',$data))
continue;
$data=trim($data);
if($data=='quit'||$data='exit'){
echo ((int)$rconnection)."退出:\r\n";
socket_shutdown($rconnection,2);
socket_close($rconnection);
unset(self::$connections[(int)$rconnection]);
continue;
}
echo "客户".$i."发送消息:".$data."\r\n";
}症状在这里:
首次telnet上去以后什么都不输入,画面定格在下面的图:我按了一个字母,马上就断线了,不知道怎么回事。如果我不设置为nonblock倒是能用了,不过这样和我的初衷就不一致了。搞了一整天了,没搞定,坛子里有没有以前弄过这个的说下吧
客户端我telnet 192.168.0.102这个上不去,但是telnet 127.0.0.1能上,是我电脑防火墙的原因吗?
程序员真不是人干的

解决方案 »

  1.   

    你的监听bind在哪个IP上? htonl(INADDR_ANY)还是直接bind在localhost了?我工作每天都写这玩意... 不过我搞C的, 不知道php里有没有fd这个概念, 还是只能foreach遍历一下fd_set rset。如果从我写C的角度,你这个代码的循环逻辑就很烂了。。 应该是遍历0..maxfd,检测每个fd是否在三个集合里,分别作对应的操作。 你telnet输一个字断开:                        if($data===false){
                                echo socket_strerror(socket_last_error());
                                echo ((int)$rconnection)."断开连接:\r\n";
                                socket_shutdown($rconnection,2);
                                socket_close($rconnection);
                                unset(self::$connections[(int)$rconnection]);
                                continue;
                            }肯定是这段代码断掉的,你自己研究研究why吧,另外TCP是字节流,你假设一次只有一条消息被read,其实可能两条msg一次性read到,所以preg_match找\r\n那里必须做成循环拆包。
      

  2.   

    绑在127.0.0.1上。fd是什么东西?我百度看到,好像说php这个socket好像底层就是C,稍有改动,应该都差不多
    楼上的猛人方便的话留个QQ,我就是对socket不懂,这两天需要搞这玩意才开始研究的。