问题描述
我的目标是将套接字连接(一次“握手”(http升级)和“已认证”(我自己的函数,使用我提供的详细信息对我的数据库进行挑战)传递给另一个PHP脚本进程(不分叉) ),以便可以将其添加到自己的套接字资源“经过身份验证的客户端”数组中并接管连接。通过sendmsg的PHP包装器发送后(socket_sendmsg-谁的PHP文档不准确,因此我主要关注的是试图在c中执行相同操作的人)
如果我发送:
socket_sendmsg($hsSocket,["iov" => [json_encode(array('action'=>'add','uID'=>$messageObj->uID,'uDatID'=>$messageObj->uDatID,'sessID'=>$messageObj->sessID))],"control" => [["level" => SOL_SOCKET,"type" => SCM_RIGHTS,"data" => [$authlogfd]]]],0);
正在发送打开的日志文件的文件描述符(如果我这样做的话)(在该resourceArray上的socket_select之后):
if(socket_recvmsg($arrayOfSocketResources,$hsSocketData,MSG_DONTWAIT)){
printf("SS:HS: got recvmsg control data\n");
print_r($hsSocketData);
if(isset($hsSocketData['control'][0]['data'][0])){
$newlogfd=$hsSocketData['control'][0]['data'][0];
$msg=json_decode($hsSocketData['iov'][0],true);
if(isset($msg['action'])&&$msg['action']=='add'){
$sendmsg=PHP_EOL."from second script".PHP_EOL;
fwrite($newlogfd,$sendmsg,strlen($sendmsg));
printf("SS:HS: got descriptor %s action:%s uID:%s uDatID:%s sessID:%s\n",$newlogfd,$msg['action'],$msg['uID'],$msg['uDatID'],$msg['sessID']);
}
然后,我在日志中看到消息“来自第二个脚本”(因此,即使关闭传递者之后,我也可以写出传递给它的文件描述符(对文件描述附加的每个进程都有计数)递增))。如果我从传递者(而不是日志文件描述符)发送该消息,这对STDOUT也有效。
当我更改为发送经过身份验证的tcp套接字客户端资源之一时,如果我转储,它将显示资源ID:
Array(
[name] =>
[control] => Array
([0] => Array
(
[level] => 1
[type] => 1
[data] => Array
(
[0] => Resource id #12
)
)
)
[iov] => Array
(
[0] => {"action":"add","uID":"816-2554846393-11","uDatID":"fe1eba892f2144b3c9ce49f79c7a8386","sessID":"9mpr38o5nrmqke0mfejvn3801l"}
)
[flags] => 0
)
问题是,当我尝试使用传递的套接字资源“获得的资源ID#12”时
socket_send(): supplied resource is not a valid Socket
在其读取资源数组中添加了“ Resource id#12”的socket_select也很烦人,抱怨它无效。
我要通过某种不同的方式传递套接字吗?我想念的东西(除了明显的东西)。
解决方法
$r = socket_sendmsg($authSocket,["iov" => [json_encode(array('uID'=>$socketMYSQL->unboxID($messageObj->uID),'uDatID'=>$messageObj->uDatID,'sessID'=>$messageObj->sessID))],"control" => [["level" => SOL_SOCKET,"type" => SCM_RIGHTS,"data" => [socket_export_stream($newSocketArrayResource),STDOUT]]]],0);
socket_export_stream()是我现在收到的fd上的var_dump时我所缺少的魔力(我认为它将套接字封装在流对象中)
resource(13) of type (Socket)
代替
resource(13) of type (stream)
和socket_getpeername()有效