Unix套接字发送接收客户端到服务器大块数据错误


Unix socket send receive client to server big chunk of data error

我在client(php)-server(c++)大量数据的通信时遇到问题。服务器(c++)无法从客户端(php)接收大块数据。当客户端发送少量信息时,一切正常,但是当我尝试发送大块(即~8kb)时,我断开了通信(不知道服务器接收什么,因为它是后台进程)。

请接收我使用的以下代码,并在可能的情况下更正它:

连接后的PHP部分(发送$sendbuf):

        socket_set_nonblock($fd);               
        $b_time = 20;
        $b_tries= 0;
        while($b_time)
        {
            if (($sc=@socket_connect($fd, $file))==FALSE && $b_tries > $b_time)
            {
                @socket_close($fd);
                return false;
            }
            else if ($sc == true)
            {   
                break;
            }
            $b_tries++;
        }
        $b_time=time();
        while($b_time)
        {
            $wd=array();
            array_push($wd,$fd); 
            if (false===($num = @socket_select($rd=NULL, $wd, $er=NULL, $select_timeout)))
            {
                @socket_close($fd);
                return $result;
            }
            else
            {
                if ($num > 0)
                {
                    if (false===($out_now=@socket_write($fd, $sendbuf, strlen($sendbuf))))
                    {
                        @socket_close($fd);
                        return false;
                    }
                    $b_time=$tm;
                    $sendbuf=substr($sendbuf,$out_now);
                    if (!strlen($sendbuf)) break;
                }
                else if ((time()-$b_time)>$timeout_write)
                {
                    @socket_close($fd);
                    return false;
                }
            }
        }

如果正常,则从服务器接收答案,但没有答案。

C++部分:

int Socket::receive ( std::string& s ) const
{
if ( current_socket < 0 ) return false; // error socket failed!
char buf [1025];
memset(buf, 0, 1025);
// cleanup string
s = "";
int done = 0;
int status_or_nbytes = 0;
char* pch;  
do {
    status_or_nbytes = ::recv ( current_socket, buf, 1024, 0 );
    if ( status_or_nbytes == 1024 )
    {   // not all message readed, instead last byte is not SPECIAL_CHAR
        if ( buf[1023] == 26 )
        {
            //std::cout << "S 26! " << std::endl;
            buf[1023] = ''0';
            done = 1;
        }
        s += buf;
    }
    else if ( status_or_nbytes > 0 ) // < 1024
    {
            if ( buf[status_or_nbytes-1] == 26 )
            {
                buf[status_or_nbytes-1] = ''0';
                done = 1;
            }
            s += buf;
    }
    if (status_or_nbytes <= 0) 
    {
        done = 1;
    }
} while (!done);

if ( status_or_nbytes == -1 )
{
    std::cout << "ERROR1" << std::endl;
    return 0;
}
else
{
    return 1;
}
}

您接收 C 代码似乎做出了以下假设。

  • 数据以 1024 或更少的块形式到达
  • 每个块都由一个神奇的 26 终止
  • 如果块小于 1024,则发生通信结束

然而,这不一定成立。操作系统可以在您的recv(...)通话中免费为您提供尽可能少的数据,即使流中仍有大量数据在等着您。交易量越高,这种情况的可能性就越大。

一旦您收到少于 1024 字节,服务器将关闭连接,PHP 脚本将看到写入错误。