我在套接字读取时观察到奇怪的行为,读取操作超时,当我的程序每字节读取字节时:只读取消息的开头,然后'socket_read'返回false。 如果读取操作是在两个字节或更多字节上完成的,则返回所有消息。
Bellow是套接字创建函数和套接字读取函数的源代码。
在读取功能中,读取前设置的时间戳为300。此时间戳对每个字节的读操作字节不起作用,因为消息“BEGIN read”和“END read”以小于一秒的间隔写入日志文件中。
程序需要读取每个字节的字节以停止在特定标记上。
任何人都有想法通过阻塞读取来启用每个字节的读取字节?
感谢您的帮助!
<?php
function getSocket($port, $address)
{
// Ouverture de la socket en attente de connexion
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
detectedErrorLog("socket_create() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n");
return false;
}
//rendre la socket réutilisable (plus d'erreur "address already in use")
if (socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1) === false) {
detectedErrorLog("socket_set_option SO_REUSEADDR failed : " . socket_strerror(socket_last_error($sock)) . "\n");
return false;
}
//la connexion doit être maintenue ouverte
if (socket_set_option($sock, SOL_SOCKET, SO_KEEPALIVE, 1) === false) {
detectedErrorLog("socket_set_option SO_KEEPALIVE failed : " . socket_strerror(socket_last_error($sock)) . "\n");
return false;
}
if (socket_bind($sock, $address, $port) === false) {
detectedErrorLog("socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n");
return false;
}
if (socket_listen($sock) === false) {
detectedErrorLog( "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n");
return false;
}
return $sock;
}
function mySocketRead($msgsock, $length, $delimiter)
{
$message = "";
$cpt = 0;
$nb_octets = 1;
socket_set_option($msgsock, SOL_SOCKET, SO_RCVTIMEO, array('sec'=>300, 'usec'=>0));
$rand_number = rand();
debugLog("BEGIN read (".$rand_number."): ".time().", timeout lecture = ".print_r(socket_get_option($msgsock, SOL_SOCKET, SO_RCVTIMEO), true));
while($cpt < $length)
{
$resp = socket_read($msgsock, $nb_octets);
if($resp !== false)
{
$message .= $resp;
$cpt+=strlen($resp);
}
//S'il n'y a plus rien à lire ou qu'on arrive à la fin du message
if ($resp == false || strpos($resp, $delimiter) !== false)
{
break;
}
}
debugLog("END read (".$rand_number."): ".time().", message = ".$message);
return $message;
}
?>