【发布时间】:2020-11-21 18:43:49
【问题描述】:
我正在尝试通过 PHP 套接字发送数据,客户端是 Arduino 设备,当我多次发送时它可以接收数据,但是如果我重置客户端(Arduino 设备),它会在几秒钟内重新启动,它说它已连接到 PHP 套接字,然后当我想通过 socket_send() 再次发送数据时它会静默失败,PHP socket_send() 不会在第一个实际错误时返回错误,只是我第二次尝试(失败) ,只有这样它才返回错误(“发送零字节”)。收到此错误后,我创建另一个socket_accept() 并成功发送消息。
什么可能导致这种情况?我希望它能够正确检测到丢失的连接,以便在需要时重新发送数据。
感觉就像它发送数据到一个旧的连接,只是在第二次尝试时才意识到,这可能吗?
socket_select() 可以解决这个问题吗?我很难理解它的作用。
澄清:如果客户端重新启动并再次连接,则向其发送数据返回int,然后返回false、false、false(除非我取消设置$accept 并再次执行socket_accept() )。如果客户端保持离线,则发送总是返回int、int、int。
int 是发送的字符串的大小。
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket\n");
// reuse any existing open port to avoid error
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");
$result = socket_listen($socket) or die("Could not set up socket listener\n");
do{
if(!isset($accept)){
echo "\nwaiting for clients";
$accept = @socket_accept($socket) or die("Could not accept incoming connection");
echo "\nclient connected";
}
// memcached will return a message here like: "my message\r\n"
$message_to_send = $memcached->get('my_socket_message');
if($message_to_send!=''){
echo "\nsending: ".$message_to_send;
$total_data_sent = @socket_send($accept, $message_to_send, strlen($message_to_send), MSG_EOR);
// if data was not send (sent to an old connection ?!)...
// then clear $accept, so a new connection is accepted
// and keep the my_socket_message variable, so message is sent again
if($total_data_sent === false){
echo "\nSEND FAILED, will retry message: ".$message_to_send;
unset($accept);
} else {
$memcached->delete('my_socket_message');
}
}
} while (true);
【问题讨论】:
-
当您说“它默默地失败”时,
@socket_send(的确切结果是什么(请为 var_dump)? socket_select 返回改变状态的套接字数量,所以$checkExcept = [$accept];和socket_select(null, null, $checkExcept);应该在出错时返回 1。 -
我第一次尝试发送并且客户端断开连接时,它返回
int(32)(字符串大小),只有当我再次调用它时,它才返回bool(false)。由于客户端将完全离线,这不可能是客户端问题,不是吗? -
如果客户端重新启动并再次连接,则向其发送数据返回
int,然后返回false、false、false(除非我取消设置$accept并执行@ 987654347@ 再次)。如果客户端保持离线,则发送始终返回int、int、int。
标签: php sockets tcp arduino iot