Hello,
I was messing around with TcpSockets after reading about them via
Communicating with sockets, but I've ran into an issue. I'm struggling to figure out why it's happening so I'd very much appreciate any help I can get.
It's probably a silly mistake.I've set up a small testing environment for myself split in two solutions, one for the client and one for the server.
If I call TcpSocket::disconnect(), whether it be from the client's side or the server's; it will not result in the other side's socket status on TcpSocket::send([...]) or TcpSocket::receive([...]) to be sf::Socket::Disconnected. It'll always end up as sf::Socket::Partial, until I call disconnect from their side.
I was using
this post from Laurent and
this post from binary1248 as references points.
These aren't exactly the most recent posts and sf::Socket::Partial status has only been recently introduced with SFML 2.3, but I'd still expect the logic to be valid.
PS: I'm mostly curious in finding out why my issue is happening. I don't plan to do anything specific with this so I wouldn't consider"alternate" solutions (such as using packets or adding a heartbeat ping) to be of much interest or help.
Thanks
Server#include <SFML\Graphics.hpp>
#include <SFML\Network.hpp>
#include <iostream>
sf::RenderWindow* serverWindow;
sf::TcpListener* listener;
sf::TcpSocket* client;
bool serverIsOpen = false;
void CloseServer()
{
std::cout << "---" << __FUNCTION__ << "---" << std::endl;
client->disconnect();
listener->close();
serverIsOpen = false;
std::cout << "---------------" << std::endl;
}
void OpenServer()
{
std::cout << "---" << __FUNCTION__ << "---" << std::endl;
serverIsOpen = true;
if (listener->listen(41852) != sf::Socket::Done)
{
std::cout << "Listen - Error" << std::endl;
}
else
{
std::cout << "Listen - OK" << std::endl;
}
if (listener->accept(*client) != sf::Socket::Done)
{
std::cout << "Accept - Error" << std::endl;
}
else
{
std::cout << "Accept - Ok" << std::endl;
}
std::cout << "---------------" << std::endl;
}
void ReceiveData()
{
std::cout << "---" << __FUNCTION__ << "---" << std::endl;
char data[5];
std::size_t received;
sf::Socket::Status status = client->receive(&data, 5, received);
std::cout << status << "- ";
switch (status)
{
case (sf::Socket::Status::Disconnected) :
std::cout << "Disconnected" << std::endl;
break;
case (sf::Socket::Status::Done) :
std::cout << "Success" << std::endl;
break;
case (sf::Socket::Status::Error) :
case (sf::Socket::Status::NotReady) :
case (sf::Socket::Status::Partial) :
default:
std::cout << "Error" << std::endl;
break;
}
std::cout << "---------------" << std::endl;
}
void SendData()
{
std::cout << "---" << __FUNCTION__ << "---" << std::endl;
char data[5] = "TEST";
sf::Socket::Status status = client->send(data, 5);
std::cout << status << "- ";
switch (status)
{
case (sf::Socket::Status::Disconnected) :
std::cout << "Disconnected" << std::endl;
break;
case (sf::Socket::Status::Done) :
std::cout << "Success" << std::endl;
break;
case (sf::Socket::Status::Error) :
case (sf::Socket::Status::NotReady) :
case (sf::Socket::Status::Partial) :
default:
std::cout << "Error" << std::endl;
break;
}
std::cout << "---------------" << std::endl;
}
int main()
{
serverWindow = new sf::RenderWindow(sf::VideoMode(400, 400), "Server Window");
listener = new sf::TcpListener;
client = new sf::TcpSocket;
client->setBlocking(true);
while (serverWindow != nullptr && serverWindow->isOpen())
{
sf::Event event;
while (serverWindow->pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
serverWindow->close();
}
else if (event.type == sf::Event::KeyPressed)
{
switch (event.key.code)
{
case (sf::Keyboard::O) :
if (!serverIsOpen)
{
OpenServer();
}
break;
case (sf::Keyboard::C) :
if (serverIsOpen)
{
CloseServer();
}
break;
case (sf::Keyboard::R) :
ReceiveData();
break;
case (sf::Keyboard::S) :
SendData();
break;
default:
break;
}
}
}
serverWindow->clear();
serverWindow->display();
}
return 0;
}
Client#include <SFML\Graphics.hpp>
#include <SFML\Network.hpp>
#include <iostream>
sf::RenderWindow* clientWindow;
sf::TcpSocket* socket;
void Connect()
{
std::cout << "---" << __FUNCTION__ << "---" << std::endl;
sf::Socket::Status status = socket->connect("127.0.0.1", 41852);
if (status != sf::Socket::Done)
{
std::cout << "Client connection attempt failed." << std::endl;
}
else
{
std::cout << "Client connection attempt succeeded." << std::endl;
}
std::cout << "---------------" << std::endl;
}
void Disconnect()
{
std::cout << "---" << __FUNCTION__ << "---" << std::endl;
socket->disconnect();
std::cout << "---------------" << std::endl;
}
void ReceiveData()
{
std::cout << "---" << __FUNCTION__ << "---" << std::endl;
char data[5];
std::size_t received;
sf::Socket::Status status = socket->receive(&data, 5, received);
std::cout << status << "- ";
switch (status)
{
case (sf::Socket::Status::Disconnected) :
std::cout << "Disconnected" << std::endl;
break;
case (sf::Socket::Status::Done) :
std::cout << "Success" << std::endl;
break;
case (sf::Socket::Status::Error) :
case (sf::Socket::Status::NotReady) :
case (sf::Socket::Status::Partial) :
default:
std::cout << "Error" << std::endl;
break;
}
std::cout << "---------------" << std::endl;
}
void SendData()
{
std::cout << "---" << __FUNCTION__ << "---" << std::endl;
char data[5] = "TEST";
sf::Socket::Status status = socket->send(data, 5);
std::cout << status << "- ";
switch (status)
{
case (sf::Socket::Status::Disconnected) :
std::cout << "Disconnected" << std::endl;
break;
case (sf::Socket::Status::Done) :
std::cout << "Success" << std::endl;
break;
case (sf::Socket::Status::Error) :
case (sf::Socket::Status::NotReady) :
case (sf::Socket::Status::Partial) :
default:
std::cout << "Error" << std::endl;
break;
}
std::cout << "---------------" << std::endl;
}
int main()
{
clientWindow = new sf::RenderWindow(sf::VideoMode(400, 400), "Client Window");
socket = new sf::TcpSocket();
socket->setBlocking(true);
while (clientWindow != nullptr && clientWindow->isOpen())
{
sf::Event event;
while (clientWindow->pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
clientWindow->close();
}
else if (event.type == sf::Event::KeyPressed)
{
switch (event.key.code)
{
case (sf::Keyboard::C) :
Connect();
break;
case (sf::Keyboard::D) :
Disconnect();
break;
case (sf::Keyboard::R) :
ReceiveData();
break;
case (sf::Keyboard::S) :
SendData();
break;
default:
break;
}
}
}
clientWindow->clear();
clientWindow->display();
}
return 0;
}