我必须制作一个函数,在该函数中,我将数据包发送到服务器,然后读取数据。过了一段时间,我有时需要使用同一个套接字再次向服务器发送数据(要求我使用相同的套接字)。
由于某种原因,读取后的第二次发送不会发送数据(它返回正确的数字(不是错误的),但服务器并没有接收到数据包)。如果我创建新的套接字并发送数据,它就可以工作了。
这里有一个例子:
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '192.168.1.179', 1455);
socket_set_option($socket,SOL_SOCKET, SO_RCVTIMEO, array("sec"=>5, "usec"=>0));
$this->socket_functions->send_message($socket,$sendMsg,$funcName);
$tmp = trim($this->socket_functions->read_packet($socket));
for($i =0; $i<10; $i++)
{
$tmp = trim($this->socket_functions->read_packet($socket));
$this->socket_functions->send_message($socket, 'AAAA', $funcName); //doesn't work
/*
///works
$socket2 = $this->socket_functions->create_socket();
$this->socket_functions->send_message($socket2, 'AAAA', $funcName);
$this->socket_functions->disconnect($socket2);
*/
}
函数create_socket执行与前3行相同的操作,因此连接数据相同。我刚刚把它拿出来,这样你就可以看到我的配置了。
对于读写,我使用函数socket_send()和socket_write()。
读包功能:
$resultMsg = "";
while(strlen($currentData = socket_read($socket,256))==256)
{
$resultMsg .=$currentData;
}
$resultMsg.=$currentData;
if(strlen($resultMsg)>1 && strpos($resultMsg,'<')>0)
{
$resultMsg = substr($resultMsg,strpos($resultMsg,'<'));
}
return $resultMsg;
发送数据包:
function create_packet($msg, $type)
{
$msg = $type.$this->convert_data->IntToAsciiChars(strlen($msg)).$msg;
$msg = chr(0).$this->convert_data->IntToAsciiChars(strlen($msg)).$msg;
return $msg;
}
function send_message($socket,$msg,$type)
{
$packet = $this->create_packet($msg,$type);
$res = socket_send($socket,$packet,strlen($packet),0);
if($res === false) return false;
return true;
}
编辑
我做了更多的测试,发现只有当我连接的服务器不断发送数据时,才会发生这种情况。在中,服务器连续发送多个数据包。如果我试图在服务器发送所有数据包之前发送数据包,则数据包不会被接收。有人知道为什么会发生这种事吗?我有一个桌面应用程序,它做同样的事情(在服务器发送数据时使用相同的套接字发送数据),但它在那里工作。有什么特别的吗?
我终于解决了这个问题。经过测试,我发现,如果我使用sendn+1次来发送消息,其中n是调用read的次数,那么我就可以发送消息了。
我真的不知道为什么会这样——也许这里有人知道?