源码:
$this->_socket = stream_socket_client("{$this->transport}://{$this->_remoteAddress}", $errno, $errstr, 0,
STREAM_CLIENT_ASYNC_CONNECT);
。
。
。
Worker::$globalEvent->add($this->_socket, EventInterface::EV_WRITE, array($this, 'checkConnection'));
请问,我故意把remoteAddress写成一个无效的地址,如3.3.3.3:3333,EV_WRITE的监听还是在4秒左右触发了checkConnection,这是为什么呢???
为啥写一个无效地址就不能触发checkConnection?
我的理解是EV_WRITE监听管道是否可写,而无效的地址没有形成管道,怎么会可写呢?
还有为什么是4秒左右触发checkConnection呢?
<?php
global $eb,$client,$time;
$time=time();
$eb=new EventBase();
$timer=new Event($eb,-1,Event::TIMEOUT,function()use(&$timer){
$timer->add(1);
});
$client=stream_socket_client("tcp://3.3.3.3:2222",$errcode,$errstr,0,STREAM_CLIENT_ASYNC_CONNECT);
$et=new Event($eb,$client,Event::WRITE,function($client){
global $time;
echo time()-$time;
});
$et->add();
$timer->add(1);
$eb->loop();
我写的一个测试用例,发现不是4秒,是7秒触发的
具体细节不知道,但是大概原因知道了,因为/proc/sys/net/ipv4/tcp_syn_retries的含义是重发SYN包的次数,而我的虚拟机这个值是2,第一次3秒,第二次4秒,这两次发完后,认为这个连接已经失败了,发了一个信号(FIN?)给event,所以触发了checkConnection。细节我再想办法了解下。
这个信号(FIN?)不光触发了WRITE,还可以触发READ,测试得出来得结果。
(第一次)1 + (第二次)2 + (才确认连接失败)4 =7 秒