简体   繁体   中英

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

I have problem with client(php)-server(c++) communications with big amount of data. Server(c++) can not receive from client (php) big chunk of data. All work fine when client send small amount of information, but when I try to send big chunk (ie. ~8kb), I got disconnection of communication (does not know what server receive because it's background process).

Please, receive following code that I use and correct it if it's possible:

PHP part after connect (it's send $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;
                }
            }
        }

// then receive answer from server if ok, but no answer.

C++ PART:

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;
}
}

Your receiving C-Code seems to make the following assumption.

  • Data arrives in chunks of 1024 or less
  • Each chunk is terminated by a magical 26
  • end of communication occurs if a chunk is smaller then 1024

This however does not have to hold true. The OS is free to supply you with as little data as it likes on your recv(...) call even if there are still large chunks of data in the stream waiting for you. This simply becomes more likely the higher the volume.

Once you receive less then 1024 byte the server closes the connection and the PHP script sees a write error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM