Hi everyone.
Thank you by advance for your help !
I have an issue and I don't know the cause.
J'ai un problème dont je n'arrive pas à identifier tout à fais la cause. First of all, I can not use the sf :: Packet class because I do not handle the "server side".
I am supposed to receive a generic message of about 60 bytes.
So I created a buffer of size 64. The problem is that at the reception I do not get the 61bytes, at least not all the time and that's what I do not understand ...
Sometimes I get the whole message, sometimes not.
The problem is that when I do not receive the whole message, the status returned is still sf::Socket::Done, therefore, no way for me to analyze whether my message is complete or not to re-call the receive() function ...
Here is my code "abbreviated" and the associated answers:
int main()
{
sf::TcpSocket socket;
std::cout << "Connexion" << std::endl;
sf::Socket::Status status = socket.connect("192.168.127.254", 9001);
std::cout << status << std::endl;
size_t received(1);
char data[64] = { 0 };
std::string str{ "" };
str = "#1Z1|\r" ;
if (socket.send(&str[0], str.size()) != sf::Socket::Done)
std::cout << "ERROR sending" << std::endl;
else
std::cout << "Message sent : " << str << std::endl;
status = socket.receive(data, 64, received);
if ( status != sf::Socket::Done)
std::cout << "ERROR reception. Status : " << status << std::endl; // Just for illustration
else
{
data[received - 1] = '\0';
str = data;
std::cout << "Message received: " << str << " (" << received << ")" << std::endl;
std::cout << "Status : " << status << std::endl;
}
// To prove that there are still some:
if (received != 61)
{
status = socket.receive(data, 64, received);
if (status != sf::Socket::Done)
std::cout << "ERROR reception. Status : " << status << std::endl; // Just to illustrate
else
{
data[received - 1] = '\0';
str = data;
std::cout << "Message received : " << str << " (" << received << ")" << std::endl;
std::cout << "Status : " << status << std::endl;
}
}
}
Here are the results in the windows console, first when it works properly and sencondly when it doesn't :
Reception OK :
Connexion
0
Message sent: #1Z1|
Message received: 1Z1p+4s+100u+2o+175n+1000b+32282B+0d+0t+0W+1P+100N+0:b+1:B+0(61)
Status : 0
Bad réception :
Connexion
0
Message sent: #1Z1|
Message received: 1Z1p+4s (8)
Statut : 0
Message received: 100u+2o+175n+1000b+32282B+0d+0t+0W+1P+100N+0:b+1:B+0 (53)
Status : 0
Status 0 correspond to sf::Socket::Done.
You see well that sometimes I do not get everything, and yet the program returns me a Done status ...
An idea of the problem and how to solve it?
Thanks by advance,
Vincent.
PS : I'm beginner, sorry if I made big mistake :p
This is very well explained in the socket tutorial:
The last difference is about the way data is transported. TCP is a stream protocol: there's no message boundary, if you send "Hello" and then "SFML", the remote machine might receive "HelloSFML", "Hel" + "loSFML", or even "He" + "loS" + "FML".
So you have to find a way to detect the end of the message within the received stream of data. If the communication protocol has no concept of boundaries, then there's no other choice but to rely on the number of bytes received.
I forgot this one ...
Well I can't predict the number of bytes received ...
As is I'm not sure there is a special incomming communication protocol, I'll check this way.
But I think that the last byte sent is the carriage return "\r". But not sure I can detect it with something like :
if (data[received-1] != '\r')
//receive again and again
This character is always the last one no ?
Thank you for you response Laurent.
Fastest resolved problem ever !
It works perfectly, just needed a little do{}while() loop ...
Quite easy, sorry for bothering...
My code for those who'd like :
bool status = false;
int i(0);
do {
socket.receive(data, 64, received);
if (data[received - 1] != '\r')
{
str += data;
status = false;
}
else
{
data[received - 1] = '\0';
str += data;
status = true;
}
++i;
} while (statut == false);
std::cout << "Message received in " << i << " times: \n" << str << std::endl;