IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GTK+ avec C & C++ Discussion :

Gestion de sockets


Sujet :

GTK+ avec C & C++

  1. #1
    Membre éclairé Avatar de Trunks
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2004
    Messages
    534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2004
    Messages : 534
    Par défaut Gestion de sockets
    Je n'ai pas trouve dans la FAQ comment on gerait les sockets en GTK+.
    En faisant quelques recherches, j'ai trouve qu'il fallait utiliser GtkSocket, mais je ne vois pas trop comment me connecter a un serveur.
    Savez-vous ou je pourrais trouver un tutorial dessus?

  2. #2
    Membre chevronné Avatar de Lunixinclar
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2006
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 416
    Par défaut
    Salut,

    Tu peux faire simple en traitant les sockets de manière classique, comme descripteurs de fichiers.

    En fait je crois que GtkSocket n'a rien à voir avec les connections réseau. Si quelqu'un qui a déjà utilisé ce widget pouvait confirmer?

    http://developer.gnome.org/doc/API/2...GtkSocket.html

    Voici un exemple pour se connecter à un serveur HTTP :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    /*
       Saisir une URL ou une IP dans la zone de texte,
       presser Entrée: un socket se connecte et récupère
       l'en-tête HTTP du serveur avec une requête HEAD.
       Lunixinclar.
    */
     
    #include <gtk/gtk.h>
    #include <string.h>
    #include <unistd.h>
    #include <netdb.h>
    #include <arpa/inet.h>
     
    GtkWidget *TxtData;
    static void TxtIP_ENTER_Pressed(GtkWidget *widget, GtkWidget *entry);
     
    /*******************************************************************************
     Point d'entrée
    ******************************************************************************/
    int main(int argc, char **argv)
    {
      GtkWidget *Fen, *vbox, *TxtIP;
      gtk_init(&argc, &argv);
     
      // Fenêtre 
      Fen = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        g_signal_connect(G_OBJECT(Fen),"destroy",G_CALLBACK(gtk_main_quit),NULL);
        gtk_container_set_border_width (GTK_CONTAINER (Fen), 4);
        gtk_window_set_default_size(GTK_WINDOW(Fen), 400, 400);
        gtk_window_set_position (GTK_WINDOW (Fen), GTK_WIN_POS_CENTER);
        vbox = gtk_vbox_new (FALSE, 0);
        gtk_container_add (GTK_CONTAINER (Fen), vbox);
        gtk_widget_show (vbox);
      // Textbox IP/serveur
      TxtIP = gtk_entry_new ();
        gtk_entry_set_max_length (GTK_ENTRY (TxtIP), 50);
        g_signal_connect (G_OBJECT (TxtIP), "activate",
    		      G_CALLBACK(TxtIP_ENTER_Pressed),(gpointer)TxtIP);
        gtk_entry_set_text (GTK_ENTRY (TxtIP), "127.0.0.1");
        gtk_editable_select_region (GTK_EDITABLE (TxtIP),0,
    				GTK_ENTRY (TxtIP)->text_length);
        gtk_box_pack_start (GTK_BOX (vbox), TxtIP, FALSE, TRUE, 0);
      // Textbox messages
      TxtData = gtk_text_view_new();
        gtk_box_pack_start (GTK_BOX (vbox), TxtData, TRUE, TRUE, 4);
     
      gtk_widget_show_all(Fen);
     
      gtk_main();
      return 0;
    }
     
    /*******************************************************************************
     * Presser Entrée pour se connecter
    ******************************************************************************/
    static void TxtIP_ENTER_Pressed(GtkWidget *widget, GtkWidget *entry)
    {
      int sk = -1;				// descripteur socket
      struct sockaddr_in ServAddr;		// addresse du serveur
      struct hostent *serveurEnt;		// description serveur
      unsigned long hostAddr;		// addr du serveur
      int i=1;
      const gchar *serveur = NULL;		// www.truc.com ou IP
      const gchar *req     = NULL;		// Requête HTTP
      const gchar *sUTF8   = NULL;		// Paquet réponse en UTF8
      char buf[2048];			// en locale
      GtkTextBuffer *pTx;
      GtkTextIter iStart;
     
      serveur = gtk_entry_get_text (GTK_ENTRY(entry));
      pTx     = gtk_text_view_get_buffer(GTK_TEXT_VIEW(TxtData));
      gtk_text_buffer_get_start_iter(pTx, &iStart);
      sUTF8 = g_strdup_printf("[Connection à  %s] ", serveur);
      gtk_text_buffer_insert (pTx, &iStart, sUTF8, -1);
     
      bzero(&ServAddr,sizeof(ServAddr));
      hostAddr = inet_addr(serveur); // convertit IP en entier long
     
      if ( (long)hostAddr != (long)-1)
        bcopy(&hostAddr, &ServAddr.sin_addr, sizeof(hostAddr));
      else  // un nom a été donné, pas une IP
      {
        serveurEnt = gethostbyname(serveur);
        if (serveurEnt==NULL)
        {
         gtk_text_buffer_insert(pTx,&iStart,"> gethostbyname = NULL\n\n",-1);
         return;
        }
        bcopy(serveurEnt->h_addr,&ServAddr.sin_addr, serveurEnt->h_length);
      }
      ServAddr.sin_port = htons(80); // Port 80 pour HTTP
      ServAddr.sin_family = AF_INET;
      if ( (sk = socket(AF_INET,SOCK_STREAM,0)) < 0)
      {
       gtk_text_buffer_insert(pTx, &iStart,"> Problème création socket.\n\n",-1);
       return;
      }
     
      if (connect(sk,(struct sockaddr *)&ServAddr, sizeof(ServAddr)) < 0)
      {
       gtk_text_buffer_insert (pTx, &iStart, "> Problème sur connect().\n\n", -1);
       return;
      }
     
      sUTF8 = g_strdup_printf("(%s)\n", inet_ntoa(ServAddr.sin_addr));
      gtk_text_buffer_insert (pTx, &iStart, sUTF8, -1);
     
      req = g_strdup_printf("HEAD / HTTP/1.1\r\n"
                            "Host:%s\r\n\r\n", serveur);
      i = send(sk, req, strlen(req), 0);
      i = recv(sk, buf, sizeof(buf), 0);
      if (i)
      {
        buf[i]=0;
        sUTF8 = g_locale_to_utf8(buf,i,NULL,NULL,NULL);
        gtk_text_buffer_insert (pTx, &iStart, sUTF8, -1);
      }
      close(sk);
      gtk_text_buffer_insert (pTx, &iStart, g_strdup("> Socket fermé.\n"), -1);
    }
    Ca donne ceci:

  3. #3
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Si je comprend une grande partie de ce qui est marqué dans la description officielle:
    Description

    Together with GtkPlug, GtkSocket provides the ability to embed widgets from one process into another process in a fashion that is transparent to the user. One process creates a GtkSocket widget and, passes the that widget's window ID to the other process, which then creates a GtkPlug with that window ID. Any widgets contained in the GtkPlug then will appear inside the first applications window.
    En effet, ca n'a strictement rien à voir avec les connexion réseau Normalement il faut voir du côté des GIOChannel qui servent apparement autant pour les fichiers, les tubes ET les sockets mais à ce que j'en lit, la portabilité n'est pas à 100% pour tous les systèmes:
    The GIOChannel data type aims to provide a portable method for using file descriptors, pipes, and sockets, and integrating them into the main event loop. Currently full support is available on UNIX platforms, support for Windows is only partially complete.
    [...]
    Donc ... bin il va falloir surement utiliser les moyens standard donc, le mieux c'est d'utiliser les BSD Sockets ou quelque chose de plus spécifique à l'implémentation
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  4. #4
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Citation Envoyé par Franck.H
    Si je comprend une grande partie de ce qui est marqué dans la description officielle:
    L'en tête me suffit :
    GtkSocket — Container for widgets from other processes
    ça semble logique puisque GTK c'est pour l'interface graphique, il faut regarder aux alentours de la glib : gnet

  5. #5
    Membre chevronné Avatar de Lunixinclar
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2006
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 416
    Par défaut
    Pour un chat j'avais utilisé une fonction super utile: gdk_input_add(). Elle permet de créer un callback par exemple on_data_Arrival() dont le code est exécuté lorsque des données arrivent.

    C'est à la fois pratique -ça rappelle les sockets de VB- et utile pour que l'interface continue de tourner sans bloquer sur recv().

    Il doit y avoir une raison pour laquelle GTK dans sa version officielle n'encapsule pas les sockets. C'est étonnant car cette lib est très portable, elle ne se restreint pas à Linux ...

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 19
    Par défaut
    sinon ta aussi la SDL_net très simple d'utilisation et portable je crois

  7. #7
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Pour un truc simple, les GIOChannels peuvent être suffisants
    Sinon y a qques libs qui utilisent la glib pour faire de la prog réseau, http://www.gnetlibrary.org/ par exemple, http://live.gnome.org/LibSoup a peut être des trucs plus bas niveau que le http, je me rappelle plus

  8. #8
    Membre éprouvé
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Par défaut
    si ça peux vous interresser, un exemple de code (portable win/linux) transformant un socket unix en GIOChannel et l'ajoutant a la main event loop

    je garanti rien du tout, c'est un bout de code qui as deja un certain age. (les debuts ou je commençais a coder )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    void
    client_gio_chan (GtkWidget * fmain, char *destaddr)
    {
      // usual stuff for sockets [start]
      struct sockaddr_in dest_addr;
      struct hostent *addr;
      int fd = socket (PF_INET, SOCK_STREAM, 0);
      if (fd == -1)
        {
          perror ("socket");
          return;
        }
      if (isalnum (destaddr[0]) == 0)
        {
          fprintf (stderr, "addr invalide\n");
          return;
        }
      else
        {
          addr = gethostbyname (destaddr);
        }
      if (addr == NULL)
        {
          herror ("gethostbyname");
          return;
        }
      dest_addr.sin_family = AF_INET;
      dest_addr.sin_port = htons (PORT);
      memcpy (&dest_addr.sin_addr, addr->h_addr_list[0], addr->h_length);
      memset (&(dest_addr.sin_zero), '\0', 8);
      // usual stuff for sockets [stop]
     
      if (connect
          (fd, (struct sockaddr *) &dest_addr, sizeof (struct sockaddr)) == -1)
        perror ("connect");
      GIOChannel *clientsock;
      clientsock = g_io_channel_unix_new (fd);
      g_io_add_watch (clientsock, G_IO_IN, client_rcpt, fmain);
      g_object_set_data (G_OBJECT (fmain), "clientsock", clientsock);
    }

Discussions similaires

  1. Bug JVM - gestion des sockets
    Par boby62423 dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 18/02/2010, 09h26
  2. gestion des sockets
    Par rodgeurette dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 04/06/2008, 11h34
  3. Gestion des Sockets Protocole TCP/IP
    Par Julien_C++ dans le forum C++Builder
    Réponses: 6
    Dernier message: 04/08/2006, 15h12
  4. Réponses: 2
    Dernier message: 12/10/2004, 13h04
  5. Gestion de sockets: fonction Accept
    Par keupon dans le forum MFC
    Réponses: 12
    Dernier message: 22/01/2004, 18h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo