Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [SOLVED] Client can't reconnect to server  (Read 3086 times)

0 Members and 1 Guest are viewing this topic.

Derpington

  • Newbie
  • *
  • Posts: 3
    • View Profile
[SOLVED] Client can't reconnect to server
« on: March 29, 2013, 09:56:59 pm »
This may be a network programming problem rather than something to do with SFML.
The problem is going like this :

Launch the server.
Launch the client.
if(selector.isReady(listener)) is running.
Shut the client down.
Timeout is detected.
Launch the client back, without closing the server.
if(selector.isReady(listener)) isn't running.

This is the server code :

#include <iostream>
#include <list>

#include <SFML/Network.hpp>

std::vector<sf::TcpSocket*> clients;
sf::SocketSelector selector;

int main(int argc, char **argv) {
    std::cout << "Update server initiated!" << std::endl;

    sf::TcpListener listener;
    listener.listen(90);
    listener.setBlocking(false);

    selector.add(listener);

    while(true) {
        if(selector.wait()) {
            if(selector.isReady(listener)) {
                sf::TcpSocket* client = new sf::TcpSocket;
                if(listener.accept(*client) == sf::Socket::Done) {
                    clients.push_back(client);
                    selector.add(*client);
                    std::cout << "Connection from client " << client->getRemoteAddress() << "!" << std::endl;
                }
            } else {
                std::vector<sf::TcpSocket*>::iterator it;
                for(it = clients.begin(); it != clients.end(); it++) {
                    sf::TcpSocket* client = *it;
                    if(selector.isReady(*client)) {
                        sf::Packet packet;
                        if(client->receive(packet) == sf::Socket::Done) {
                            std::string data;
                            packet >> data;
                            std::cout << "Received data : " << data << std::endl;
                            if(data[0] == '0') {
                                std::string message = data.substr(1);
                                if(message == "abstergo") {
                                    sf::Packet response;
                                    std::string responseString = "1";
                                    response << responseString;
                                    std::cout << "Client " << client->getRemoteAddress() << " logged in." << std::endl;
                                    client->send(response);
                                }
                            }
                        } else {
                            std::cout << "Timeout detected from " << (*it)->getRemoteAddress() << std::endl;
                            (*it)->disconnect();
                            selector.remove(**it);
                            delete (*it);
                            it = clients.erase(it);
                            it--;
                        }
                    }
                }
            }
        }
    }

    std::cin.get();
    return 0;
}
 
« Last Edit: March 30, 2013, 12:46:40 am by Derpington »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Client can't reconnect to server
« Reply #1 on: March 29, 2013, 10:05:46 pm »
Any message in the console?

You can't reuse the same port so quickly, there's a short delay. That may explain your problem.

By the way, checking the the return value of functions that return a status (TcpListener::listen) is strongly recommended ;)
Laurent Gomila - SFML developer

Derpington

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Client can't reconnect to server
« Reply #2 on: March 29, 2013, 10:12:14 pm »
The console output when I proceed to the steps from my first post is :
Quote
Update server initiated!
Connection from client 192.168.1.1!
Timeout detected from 192.168.1.1

As you can see there's nothing stating the connection from the second client.

Regarding your second point, which port are you referring to? The listener's port?

Derpington

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Client can't reconnect to server
« Reply #3 on: March 30, 2013, 12:46:15 am »
I changed my server code to this and it works fine now, but I don't know exactly why :

#include <iostream>
#include <list>

#include <SFML/Network.hpp>

int main(int argc, char **argv) {
    std::cout << "Update server initiated!" << std::endl;

    std::vector<sf::TcpSocket*> clients;

    sf::TcpListener listener;
    if(listener.listen(90) != sf::Socket::Status::Done)
        std::cout << "Couldn't listen to port 90!" << std::endl;
    listener.setBlocking(false);

    sf::SocketSelector selector;
    selector.add(listener);

    while(true) {
        if(selector.wait()) {
            if(selector.isReady(listener)) {
                sf::TcpSocket* client = new sf::TcpSocket;
                if(listener.accept(*client) == sf::Socket::Status::Done) {
                    std::cout << "Connection from client " << client->getRemoteAddress() << "!" << std::endl;
                    clients.push_back(client);
                    selector.add(*client);
                }
            } else {
                for(int i = 0; i < clients.size(); ++i) {
                    if(selector.isReady(*clients[i])) {
                        sf::Packet packet;
                        if(clients[i]->receive(packet) == sf::Socket::Status::Done) {
                            std::string data;
                            packet >> data;
                           if(data[0] == '1') {
                                std::string message = data.substr(1);
                                if(message == "abstergo") {
                                    sf::Packet response;
                                    std::string responseString = "1";
                                    response << responseString;
                                    std::cout << "Client " << clients[i]->getRemoteAddress() << " logged in." << std::endl;
                                    clients[i]->send(response);
                                }
                            } if(data[0] == '2') {
                                std::cout << "Received hearbeat from " << clients[i]->getRemoteAddress() << "." << std::endl;
                            }
                        } else {
                            std::cout << "Timeout detected from " << clients[i]->getRemoteAddress() << std::endl;
                            selector.remove(*clients[i]);
                            delete clients[i];
                        }
                    }
                }
            }
        }
    }

    std::cin.get();
    return 0;
}
 

Also, for future reference :
#include <iostream>
#include <vector>
#include <string>
#include <SFML/Network.hpp>

void doServer() {
    std::cout << "Started server. " << std::endl;
    std::vector<sf::TcpSocket*> clients;

    sf::TcpListener listener;
    listener.listen(90);

    sf::SocketSelector selector;
    selector.add(listener);

    while(true) {
        if(selector.wait()) {
            if(selector.isReady(listener)) {
                sf::TcpSocket* client = new sf::TcpSocket();
                if(listener.accept(*client) == sf::Socket::Status::Done) {
                    std::cout << "Accepted new connection from " << client->getRemoteAddress() << ". " << std::endl;
                    clients.push_back(client);
                    selector.add(*client);
                }
            } else {
                for(int i = 0; i < clients.size(); ++i) {
                    if(selector.isReady(*clients[i])) {
                        sf::Packet packet;
                        if(clients[i]->receive(packet) == sf::Socket::Status::Done) {
                            std::string message;
                            packet >> message;

                            std::cout << "Received message from " << clients[i]->getRemoteAddress() << " : " << message << std::endl;
                        } else {
                            std::cout << "Client " << clients[i]->getRemoteAddress() << " disconnected." << std::endl;
                            selector.remove(*clients[i]);
                            delete clients[i];
                        }
                    }
                }
            }
        }
    }
}

void doClient() {
    std::cout << "Started client. " << std::endl;
    sf::TcpSocket socket;
    if(! socket.connect("127.0.0.1", 90) == sf::Socket::Status::Done) {
        std::cout << "Couldn't connect to server." << std::endl;
        return;
    } else
        std::cout << "Connected to server." << std::endl;
    std::cin.ignore(1000);
    std::cin.get();
}

int main(int argc, char **argv) {
    std::cout << "c/s ? ";
    std::string input;
    std::cin >> input;
    if(input == "c")
        doClient();
    if(input == "s")
        doServer();

    std::cin.get();
    return 0;
}
 
« Last Edit: March 30, 2013, 12:51:20 am by Derpington »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: [SOLVED] Client can't reconnect to server
« Reply #4 on: March 30, 2013, 12:07:31 pm »
I don't know (don't really have time to investigate, sorry).

Why do you put a non-blocking socket in a selector? It just doesn't make sense.
Laurent Gomila - SFML developer

 

anything