Signaler

Definir qui est le serveur qui est le client ??? [Résolu]

Posez votre question poparnassus 390Messages postés vendredi 28 mars 2014Date d'inscription 19 juillet 2017 Dernière intervention - Dernière réponse le 8 févr. 2017 à 14:12 par poparnassus
Salut à tous et bonne année ca faisait quelque mois que je n'avais pas poster ici :----))) ,

Suite à mes poste précédent, je continu à développer une interface en C sous windows pour piloter un véhicule radiocommande, donc je souhaite utiliser le reseau wifi pour communiquer sur un raspberry, donc je dois utiliser les sockets !
Ma question, comment definir qui est le serveur qui est le client ?

Mon interface, les données générées par mon joystick sont stocker dans un tableau et doivent etre envoyer sur mon rasbperry, mais j'arrive pas à situer qui est le serveur/client car l'interface envoie les données sur le raspberry, le rasbperry transmet c'est données à la carte qui controle les moteurs, mais le rasbperry doit me retourner si les données ont été traiter par la carte de controle ou non., A tenir compte qu'il y a des capteurs sur la carte de controle, et sur le Raspb des contacteurs qui sont piloter via les gpio.

Ou alors es que je dois coder une appli serveur en C sur mon pc qui tourne en parrallele, et du coup mon interface et mon raspberry devienne tous les 2 des clients !!?? Ou je dis une connerie !

Je suis un peu perdu,
je vous remercie de vos future explication ^^

mon premier organnigrame ^^
Afficher la suite 
Utile
+0
plus moins
Salut poparnassus,

Puisque c'est ton véhicule qui est à l'écoute des ordres envoyés à partir du PC, le serveur devrait être sur le Rapsberry et non sur le PC sur une architecture client - serveur.

Mais tu peux aussi faire du peer-to-peer, si le véhicule peut avoir besoin d'envoyer une information non sollicitée au PC (par exemple : mes batteries sont faibles, mon capteur IR ne fonctionne plus, etc.).

Tu peux faire tout cela en C de zéro avec les sockets.

Ou, si tu te limites à une architecture client - serveur, vu que tu as à ta disposition un Rapsberry, tu peux mettre dessus un serveur Web, et gérer l'exécution des ordres par des requêtes http GET (ou POST) envoyées au serveur, avec des scripts du côté serveur en Php, ou cgi Perl, Python, ou Bash, pour envoyer tes commandes sur les gpio.

Cela pourrait être plus facile qu'en C bien que plus consommateur en ressources.


Dal
[Dal] 4356Messages postés mercredi 15 septembre 2004Date d'inscription ContributeurStatut 13 juillet 2017 Dernière intervention - 7 févr. 2017 à 16:47
non, c'est assez simple, et tu peux bazarder les sockets dans ton cas, sauf si tu veux te passer du serveur Web pour communiquer avec les gpio et le faire en C (avec un truc du genre http://www.airspayce.com/mikem/bcm2835/).

mais tu dis que tu as déjà installé un serveur web sur le Rapsberry et que :

Les gpio:
Quand je suis connecter en ssh, si je veux activer une borne j'entre c'est commande là dans le shell

gpio -g mode 4 out //je passe la borne en mode sortie
gpio -g write 4 1 //1 pour borne acitve
gpio -g write 4 0 //0 pour borne desactiver


Donc, si tu veux utiliser cet exécutable "gpio" de cette façon, tu peux paramétrer Apache pour gérer les scripts cgi, et exécuter un script en Bash (Perl, Python,... ou même C mais je ne vois pas l'intérêt du C ici puisque tu vas faire des appels système à la commande exécutable "gpio" en question), qui va envoyer ces commandes.

https://linuxconfig.org/simple-cgi-and-apache-examples-on-ubuntu-linux

Depuis ton programme sur le PC, tu peux utiliser le C pour envoyer des requêtes GET, par exemple, avec libcurl (vois cette procédure d'installation sous Windows : http://www.commentcamarche.net/faq/35736-installer-sous-codeblocks-avec-mingw-une-bibliotheque-librairie-compilee, ou Perl, Python (ce sera plus facile dans ces langages),...

tes requêtes seront du genre :

GET http://ip.du.rapsberry/cgi-bin/manoeuvrer.sh?angleroues=0&vitesse=12

le script peut renvoyer éventuellement le résultat de l'exécution de la commande "gpio", si tu le captures et le renvoies sur la sortie standard, de façon à ce que le PC ait le résultat de l'exécution de la requête GET.

Choisis le langage de script cgi avec lequel tu es le plus à l'aise.

Quand tu dis peer-to-peer c'est avec les soket

en C oui

On pourrait aussi imaginer un autre moyen de communication si le véhicule doit communiquer une info sans être sollicité par le PC, mais le faire en C serait sans doutes plus efficace.


Dal
Répondre
[Dal] 4356Messages postés mercredi 15 septembre 2004Date d'inscription ContributeurStatut 13 juillet 2017 Dernière intervention - 7 févr. 2017 à 17:02
l'avantage de le faire avec les sockets est que tu auras, normalement, moins de latence, que tu pourras utiliser UDP au lieu de TCP pour accélérer encore les temps de réaction,...

du côté des moins : c'est plus long à coder et plus laborieux :-)
Répondre
poparnassus 390Messages postés vendredi 28 mars 2014Date d'inscription 19 juillet 2017 Dernière intervention - 7 févr. 2017 à 18:37
ok je vais coder en C sur le raspberry étant donner que je commence à comprendre la programmation en C, j'ai réussi cette aprés midi a comprendre et faire marcher en local les socket avec client et serveur !! Quelque détaille a éclaircir mais ça va le faire !

Du coup, tu me conseilles de coder le serveur sur le raspberry ?
Répondre
poparnassus 390Messages postés vendredi 28 mars 2014Date d'inscription 19 juillet 2017 Dernière intervention - 7 févr. 2017 à 18:42
Par contre j'avais lue les differenncce entre udp et tcp et si j'ai bien compris je peux utiliser le protocole tcp pour le gpio car la j'ai besoin d'un "retour" avec le CRC
et UDP pour commander mon moteur puissque la je n'ai pas besoin de retour !
Répondre
yg_be 2870Messages postés lundi 9 juin 2008Date d'inscription ContributeurStatut 26 juillet 2017 Dernière intervention - 7 févr. 2017 à 21:25
avec udp tu n'as ni retour, ni garantie que tous les messages sont bien arrivés à destination dans le bon ordre.
Répondre
Donnez votre avis
Utile
+0
plus moins
En faite c'est pas si simple les socket ^^

Serveur:
int main(void)
{
    #if defined (WIN32)
        WSADATA WSAData;
        int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
    #else
        int erreur = 0;
    #endif

    /* Socket et contexte d'adressage du serveur */
    SOCKADDR_IN sin;
    SOCKET sock;
    char buffer[32];

    socklen_t recsize = sizeof(sin);

    /* Socket et contexte d'adressage du client */
    SOCKADDR_IN csin;
    SOCKET csock;
    socklen_t crecsize = sizeof(csin);

    int sock_err;
    int nombre_de_caractere;


    /* Si les sockets Windows fonctionnent */
    if(!erreur)
    {
        /* Création d'une socket */
        sock = socket(AF_INET, SOCK_STREAM, 0);

        /* Si la socket est valide */
        if(sock != INVALID_SOCKET)
        {
            printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);

            /* Configuration */
            sin.sin_addr.s_addr = htonl(INADDR_ANY);  /* Adresse IP automatique */
            sin.sin_family = AF_INET;                 /* Protocole familial (IP) */
            sin.sin_port = htons(PORT);               /* Listage du port */

            sock_err = bind(sock, (SOCKADDR*)&sin, recsize);
            if(sock_err!=0)
            {
                printf("Impossible d'ecouter ce port: %d \n",sock_err);
            }
            else
            {
                printf("Bind OK\n");

            }

            sock_err=99;
            while(sock_err!=0)// Boucle tant qu'une demande de session (SYN) tcp n'a pas été reçu
            {
                sock_err = listen(sock, 5);
                printf("Listen OK PORT: %d \n", PORT);


                // Acceptation de la demande
                printf("Patientez pendant que le client se connecte sur le port %d...\n", PORT);
                csock=accept(sock, (SOCKADDR*)&csin, &crecsize);
                if(sock_err==SOCKET_ERROR)
                {
                    printf("\nDesole, je ne peux pas accepter la session TCP du a l'erreur : %d \n",WSAGetLastError());
                    return EXIT_FAILURE;
                }
                else
                {
                    printf("Un client se connecte avec la socket %d de %s:%d \n", csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port));

                }

                //RECEPTION DONNEES
                nombre_de_caractere=recv(sock,buffer -1,32,0);
                if(nombre_de_caractere==SOCKET_ERROR)
                {
                    printf("Donnes non transmise \n");
                }
                else
                {
                    buffer[nombre_de_caractere]=0;
                    printf("Donnes client: \n %s",buffer);
                }

            }

            shutdown(csock, 2);
        }
        else
        {
            printf("erreur socket\n");
        }
             /* Fermeture de la socket client et de la socket serveur */
            printf("Fermeture de la socket client\n");
            closesocket(csock);
            printf("Fermeture de la socket serveur\n");
            closesocket(sock);
            printf("Fermeture du serveur terminee\n");
    }

    #ifdef WIN32
       WSACleanup();
    #endif

    return EXIT_SUCCESS;
}



Client:
int main(void)
{
    #if defined (WIN32)
        WSADATA WSAData;
        int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
    #else
        int erreur = 0;
    #endif

    SOCKET sock;
    SOCKADDR_IN sin;
    char buffer[32] ;
    int nombre_de_caractere;

    //Init structure
    Input input;
    input.PRoueG = 0;
    input.PRoueD = 0;

    if(!erreur)
    {
         /* Création de la socket */
        sock = socket(AF_INET, SOCK_STREAM, 0);

        /* Configuration de la connexion */
        sin.sin_addr.s_addr = inet_addr("127.0.0.1");
        sin.sin_family = AF_INET;
        sin.sin_port = htons(PORT);

        /* Si le client arrive à se connecter */
        if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
        {
            printf("Connexion à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));

        }
        /* sinon, on affiche "Impossible de se connecter" */
        else
        {
            printf("Impossible de se connecter\n");
        }

        //ENVOI DONNEES
        strcpy(buffer,"Bonjour"); //copy la chaine dans buffer
        nombre_de_caractere=send(sock,buffer,strlen(buffer),0);
        if(nombre_de_caractere==SOCKET_ERROR)
        {
            printf("Impossible d'envoyer les donnees \n");
        }
        else
        {
            printf("Envoyer au serveur: %s\n",buffer);
        }
        system("pause");

        /* On ferme la socket précédemment ouverte */
        closesocket(sock);

        #if defined (WIN32)
            WSACleanup();
        #endif
    }
    return EXIT_SUCCESS;
}




RESULTAT SERVEUR
La socket 236 est maintenant ouverte en mode TCP/IP
Bind OK
Listen OK PORT: 23
Patientez pendant que le client se connecte sur le port 23...
Un client se connecte avec la socket 240 de 127.0.0.1:52603
Donnes non transmise
Fermeture de la socket client
Fermeture de la socket serveur
Fermeture du serveur terminee

Process returned 0 (0x0)   execution time : 3.965 s
Press any key to continue.

CLIENT
Connexion Ó 127.0.0.1 sur le port 23
Envoyer au serveur: Bonjour
Appuyez sur une touche pour continuer...


Je comprends pas pourquoi le serveur ne m'affiche le buffer = Bonjour
et en plus je souhaite que le serveur boucle meme si il nya pas de client
Donnez votre avis
Utile
+0
plus moins
je viens de trouver mon erreur sur la socket
ligne 85 SERVEUR
nombre_de_caractere=recv(sock,buffer -1,32,0);
qui devient
nombre_de_caractere=recv(csock,buffer,32,0);
par contre j'arrive pas a faire boucler le serveur, une boucle pour si un le client se deconnecte, le serveur boucle en attente de co, et une autre boucle pour continuer la reception tant qun client est connecter !

Je continue mes recherche !
Donnez votre avis

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !