I am coding simple networking system based on sfml-network liblary and tcp sockets.
When i compile and run my program i am getting that output on screen(screenshot).
It looks like selector.wait() (Server.cpp:20) is not waiting for any packet and selector.isReady(TCPSOCKET) (Server.cpp:43)
is not checking correctly if client is sending package to server.
Code: main.cpp
#include <iostream>
#include "Server.h"
int main()
{
int mode = 0;
std::cin >> mode;
if(mode == 0)
{
Server server(55200);
}else if(mode == 1){
sf::TcpSocket socket;
if (socket.connect("localhost", 55200) != sf::Socket::Done)
{
std::cout << "Error1\n";
}
//Sleep(2000);
sf::Packet packet;
packet << 11;
if (socket.send(packet) != sf::Socket::Done)
{
std::cout << "Error2\n";
}
}
std::cin.get();
std::cin.get();
}
Server.h
#pragma once
#include <SFML/Network.hpp>
#include <vector>
class Server
{
private:
sf::TcpListener listener;
std::vector<sf::TcpSocket*> clients;
sf::SocketSelector selector;
unsigned short port;
public:
Server(unsigned short port);
~Server();
};
Server.cpp
#include "Server.h"
#include <iostream>
#include <SFML/Network.hpp>
#include <vector>
Server::Server(unsigned short pport)
{
port = pport;
std::cout << "Starting Server....\n";
if (listener.listen(port) != sf::Socket::Done)
{
std::cout << "Failed while starting listening on port: " << port << std::endl;
return;
}
selector.add(listener);
while(true)
{
if (selector.wait())
{
//new connection
if (selector.isReady(listener))
{
std::cout << "New connection!!\n";
sf::TcpSocket* tmp = new sf::TcpSocket; // !!!!!!!!!!!
if (listener.accept(*tmp) != sf::Socket::Done)
{
std::cout << "Error while accepting new connection\n";
delete tmp;
}
else {
selector.add(*tmp);
clients.push_back(tmp);
}
}
else {
for (int i = 0; i < clients.size(); i++)
{
//new incoming packet
if(selector.isReady(*(clients[i])))
{
sf::Packet pakiet;
if (clients[i]->receive(pakiet) != sf::Socket::Done)
{
std::cout << "Error while receiving packet\n";
}
else {
int x;
pakiet >> x;
std::cout << "Recived new data!!!: " << x << std::endl;
}
}
}
}
}
}
}
Server::~Server()
{
for (int i = 0; i < clients.size();i++)
{
delete clients[i];
}
}
You created a client which connected to the server, sent one package and at the end of the scope was destroyed. Socket at the client side doesn't exist and the connection between client-server is closed. So, how do you want to get the information about closed connection at server side ?
Function isReady
returns true, then you call receive
for this socket and as output you get one of Status codes: Done, NotReady, Disconnected, Error. You need to check if status is Disconnected, if so, the client socket should be removed from selector.
if(selector.isReady(*(clients[i])))
{
sf::Packet pakiet;
if ( clients[i]->receive(pakiet) == sf::Socket::Done)
{
// process data
}
else if ( clients[i]->receive(pakiet) == sf::Socket::Disconnected ) {
// delete socket, remove from selector
}
else {
//
}
}