SFML community forums

Help => Network => Topic started by: roccio on August 19, 2014, 03:58:11 pm

Title: TCP send big buffer
Post by: roccio on August 19, 2014, 03:58:11 pm
Hello,
I have a server that must send an image (stored in memory as a unsigned char* ) to a client.
What is the best option?

Thanks
Title: Re: TCP send big buffer
Post by: Hiura on August 19, 2014, 04:48:02 pm
That's a very general question: the best option according to which criterions?

My advice: read the doc, chose one solution and just go for it. If one day you need to optimise this part of your software, then, and only then, come back to it.
Title: Re: TCP send big buffer
Post by: roccio on August 20, 2014, 01:33:58 pm
I have read the documentation, but I can't make things work.
I have a big char array (it's an image) that I want to send to a client very fast. So I don't know how to use sf::packet for this nor to the client side for receiving such buffer.
Hope it's a little clearer now.

Thank you.
Title: Re: TCP send big buffer
Post by: Hiura on August 20, 2014, 05:05:50 pm
You don't have to use sf::Packet for everything. Here it sounds easier to use what's describe in the Sending and receiving data tutorial (http://sfml-dev.org/tutorials/2.1/network-socket.php#sending-and-receiving-data). Just send your buffer as is.
Title: Re: TCP send big buffer
Post by: roccio on August 20, 2014, 05:09:52 pm
I have seen this opportunity, but i have problems with the size. I have to put the send in a loop (and so the receive), but with standard sockets the send returns the number of bytes sent. sf::socket don't, so how can I send the whole buffer in a loop?
Title: Re: TCP send big buffer
Post by: Hiura on August 20, 2014, 05:19:24 pm
The doc says:

Quote
Status sf::TcpSocket::send(const void* data, std::size_t size)

Send raw data to the remote peer.

This function will fail if the socket is not connected.

Parameters
data   Pointer to the sequence of bytes to send
size   Number of bytes to send

Returns
Status code

It will simply send everything in one go.

If still not convinced, look at the implementation  ;)

Socket::Status TcpSocket::send(const void* data, std::size_t size)
{
    // Check the parameters
    if (!data || (size == 0))
    {
        err() << "Cannot send data over the network (no data to send)" << std::endl;
        return Error;
    }

    // Loop until every byte has been sent
    int sent = 0;
    int sizeToSend = static_cast<int>(size);
    for (int length = 0; length < sizeToSend; length += sent)
    {
        // Send a chunk of data
        sent = ::send(getHandle(), static_cast<const char*>(data) + length, sizeToSend - length, flags);

        // Check for errors
        if (sent < 0)
            return priv::SocketImpl::getErrorStatus();
    }

    return Done;
}
Title: Re: TCP send big buffer
Post by: roccio on August 21, 2014, 10:35:01 am
Ok, thank you very much.
Now my problem is in the receiving client....

 :-\

Will receive read a big amount of data or i need to loop?
I have done a test, but I can't receive the right things.
Title: Re: TCP send big buffer
Post by: Laurent on August 21, 2014, 11:48:38 am
You need to loop on the receiving side.
Title: Re: TCP send big buffer
Post by: roccio on August 21, 2014, 01:37:58 pm
Ok, thanks. I think that I must send the lenght of buffer, so the receiver can loop correctly.

Title: Re: TCP send big buffer
Post by: Laurent on August 21, 2014, 02:07:09 pm
Indeed. TCP is a stream protocol, which means that there's no concept of "message boundaries" on the receiving side. You know that your data has been transfered correctly, and is in the right order, but you have no idea where it ends unless you handle it explicitly, either by sending the size first, or by using some special delimiter character (not applicable here).
Title: Re: TCP send big buffer
Post by: roccio on August 21, 2014, 02:52:54 pm
Thank you very much, with your help and looking at the voip example I maneged to get it work.

I used the format

sf::Packet packet;
packet << bufferSizeInBytes;
packet.append(buffer);
socket.send(packet);

so the client can loop while bufferSizeInBytes as been reached.
Title: Re: TCP send big buffer
Post by: Laurent on August 21, 2014, 03:35:59 pm
If you use sf::Packet then things are totally different... You don't need to loop, and you don't need to send the size of the buffer. sf::Packet already does that for you.
Title: Re: TCP send big buffer
Post by: roccio on August 21, 2014, 05:11:49 pm
I will try. Thank you Laurent.