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

Langage PHP Discussion :

Socket Lire et ecrire avec le même navigateur


Sujet :

Langage PHP

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 17
    Points : 12
    Points
    12
    Par défaut Socket Lire et ecrire avec le même navigateur
    Bonjour,

    J'ai réalisé des sockets php (client et serveur) mais je me heurte à un problème, lorsque dans mon onglet 1 j'attends des données, je ne peux pas écrire avec une nouvelle socket grâce à l'onglet 2.

    Je ne sais pas si l'option non block peut résoudre mon problème, je n'ai pas bien compris comment m'en servir.

    Par ailleurs, lorsque j'écoute mon serveur, dès que j'ai la réponse, je ferme ma connexion, ce n'est pas comme ceci que Stephane Eyskens fait, il affiche l'ip:port dans une frame, recupère le contenu d'avant et ajout le nouveau message.

    Serveur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/local/php53/bin/php-cgi -q
    <?php
     
    set_time_limit (0);
    ob_implicit_flush();
    require_once 'includes/application_top.php';
    error_reporting(E_ALL);
    // SOCKET_SERVER localhost
    // SOCKET_PORT_ORDER 8081
    $socket = new Socket(SOCKET_SERVER, SOCKET_PORT_ORDER); // include/configure.php && administration/include/configure.php
    $socket->start();
    $socket->listen();

    Client (lecture) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $socket = new Socket(SOCKET_SERVER, $_REQUEST['port']);
    $socket->read();
    Client (écriture) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $socket = new Socket('localhost', '8081');
    var_dump($socket->write('Bonjour : ' . date('H:i:s')));
    La console serveur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Nouveau client connecté : Resource id #66
    Total des clients : 1
    Message reçu de Resource id #67 : Bonjour : 12:48:07
    Diffusion du message Bonjour : 12:48:07
    Ressource Resource id #66...OK
    Fermeture de la socket Resource id #67
    Voici la classe que j'utilise :

    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
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    class Socket {
     
        private $adress;
        private $port;
        private $socket;
        private $clients = array();
        private $buffer  = 128;
        private $new     = 'yo';
     
        public function __construct($adress, $port) {
            $this->adress = $adress;
            $this->port   = $port;
            $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        }
     
        /**
         * Démarre la socket et l'écoute
         * @return  Mixed   String erreur | rien
         */
        public function start()
        {
            echo PHP_EOL;
            echo '==============================';
            echo PHP_EOL;
            echo 'Création de la socket...';
            if ($this->socket === false) {
                echo PHP_EOL . __FILE__ . ':' . __LINE__ . PHP_EOL . PHP_EOL . 'socket_create() a échoué raison : ' . socket_strerror(socket_last_error()) . PHP_EOL;
                exit;
            } else {
                echo 'OK' . PHP_EOL;
            }
     
            echo 'Connexion à la socket ' . $this->adress . ':' . $this->port . '...';
            if (!socket_bind($this->socket, $this->adress, $this->port)) {
                echo PHP_EOL . __FILE__ . ':' . __LINE__ . PHP_EOL . PHP_EOL . 'socket_bind() a échoué adresse : ' . $this->adress . ':' . $this->port . ' raison : ' . socket_strerror(socket_last_error()) . PHP_EOL;
                socket_close($this->socket);
                exit;
            } else {
                echo 'OK' . PHP_EOL;
            }
     
            echo 'Ecoute de la socket...';
            if (!socket_listen($this->socket)) { // Start listening for connections
                echo PHP_EOL . __FILE__ . ':' . __LINE__ . PHP_EOL . PHP_EOL . 'socket_listen() a échoué adresse : ' . $this->adress . ':' . $this->port . ' raison : ' . socket_strerror(socket_last_error()) . PHP_EOL;
                socket_close($this->socket);
                exit;
            } else {
                echo 'OK' . PHP_EOL;
            }
            echo '==============================' . PHP_EOL;
        }
     
        /**
         * A démarrer sur le serveur #!/usr/local/php53/bin/php-cgi -q
         * Ecoute l socket
         * @return type
         */
        public function listen()
        {
            echo 'Prêt à écouter les clients';
     
            if ($this->socket === false) {
                echo PHP_EOL . __FILE__ . ':' . __LINE__ . PHP_EOL . PHP_EOL . 'listen() a échoué adresse : ' . $this->adress . ':' . $this->port . ' raison : ' . socket_strerror(socket_last_error()) . PHP_EOL;
                $this->closeSocket();
                exit;
            }
     
            echo '...OK' . PHP_EOL;
            echo 'Nombre de client : ' . count($this->clients) . PHP_EOL;
            echo '==============================' . PHP_EOL;
     
            while (true) : // Loop continuously
     
                if (!($ressource = socket_accept($this->socket))) { // plus de socket
                    $error = socket_last_error($this->socket);
                    if ($error != 11 && $error != 115) {
                        echo PHP_EOL . PHP_EOL . __FILE__ . ':' . __LINE__ . PHP_EOL . PHP_EOL . 'socket_accept() a échoué adresse : ' . $this->adress . ':' . $this->port . ' raison : ' . socket_strerror($this->socket) . PHP_EOL;
                    }
                    //exit;
                } else {
                    $this->readAndWrite($ressource);
                }
     
            endwhile;
        }
     
        /**
         * Récupère les nouvelles sockets
         * @param Socket $ressource
         */
        private function readAndWrite($ressource)
        {
            if (!is_resource($ressource)) {
                echo PHP_EOL . PHP_EOL . __FILE__ . ':' . __LINE__ . PHP_EOL . PHP_EOL . 'is_resource() a échoué adresse : ' . $this->adress . ':' . $this->port . ' raison : ' . socket_strerror(socket_last_error()) . PHP_EOL;
                //exit;
            }
     
     
            // si ecriture on transmet
            // sinon ecoute, on le stock avec les autres.
     
            $buffer = socket_read($ressource, $this->buffer);
     
            if (!empty($buffer) && $buffer === 'kill') {
                $this->clients[] = $ressource;
                echo 'Kill...' . PHP_EOL;
                $this->closeSocket();
            } elseif (!empty($buffer) && $buffer != $this->new) {
                echo 'Message reçu de ' . $ressource . ' : ' . $buffer . PHP_EOL;
                $this->writeToClient($buffer);
                echo 'Fermeture de la socket ' . $ressource . PHP_EOL;
            } elseif (!in_array($ressource, $this->clients)) { // Nouveau client
                $this->clients[] = $ressource;
                echo 'Nouveau client connecté : ' . $ressource . PHP_EOL;
                echo 'Total des clients : ' . count($this->clients) . PHP_EOL;
            }
        }
     
        /**
         * Notification de à tous les clients connectés
         * @param String $msg
         */
        private function writeToClient($msg)
        {
            echo 'Diffusion du message ' . $msg . PHP_EOL;
     
            foreach ($this->clients as $key => $socket) :
                if (!is_resource($socket)) {
                    unset($this->clients[$key]);
                } else {
     
                    echo 'Ressource ' . $socket . '...';
     
                    if (!@socket_write($socket, $msg, strlen($msg))) {
                        //echo PHP_EOL . PHP_EOL . __FILE__ . ':' . __LINE__ . PHP_EOL . PHP_EOL . 'socket_write() a échoué adresse : ' . $this->adress . ':' . $this->port . ' raison : ' . socket_strerror(socket_last_error()) . PHP_EOL;
                        unset($this->clients[$key]);
                        echo 'ECHEC : ressource fermée' . PHP_EOL;
                    } else {
                        echo 'OK' . PHP_EOL;
                    }
     
                }
            endforeach;
        }
     
        /**
         * Déconnecte tous les clients
         */
        private function disconnectAllClient()
        {
            echo 'Nombre de client : ' . count($this->clients) . PHP_EOL;
            $this->writeToClient('Le serveur va être arrêté.');
     
            foreach ($this->clients as $key => $socket) :
                if (!is_resource($socket)) {
                    echo 'Déconnexion du client : ' . $socket . PHP_EOL;
                    @socket_close($socket);
                }
            endforeach;
        }
     
        /**
         * Ferme la socket mère
         */
        private function closeSocket()
        {
            $this->disconnectAllClient();
     
            if ($this->socket !== null) {
                echo 'Fermeture de la session...';
                socket_shutdown($this->socket, 1);//remote host yet can read
                usleep(500);//wait remote host
                socket_shutdown($this->socket, 0);//close reading
                socket_close($this->socket);//finaly we can free resource
                echo 'OK' . PHP_EOL;
            }
     
            exit(PHP_EOL . 'Socket fermée.' . PHP_EOL);
        }
     
        /**
         * Client
         */
     
        public function read()
        {
            if (!@socket_connect($this->socket, $this->adress, $this->port)) {
                echo PHP_EOL . __FILE__ . ':' . __LINE__ . PHP_EOL . PHP_EOL . 'socket_connect() a échoué adresse : ' . $this->adress . ':' . $this->port . ' raison : ' . socket_strerror(socket_last_error()) . PHP_EOL;
                return null;
            }
     
            socket_write($this->socket, $this->new, strlen($this->new));
     
            $i = 0;
     
            while ($i < 10) :
                echo socket_read($this->socket, $this->buffer);
                sleep(1);
                $i++;
            endwhile;
     
            echo '<hr>';
     
            socket_close($this->socket);
        }
     
        public function write($msg)
        {
            if (!@socket_connect($this->socket, $this->adress, $this->port)) {
                //echo PHP_EOL . __FILE__ . ':' . __LINE__ . PHP_EOL . PHP_EOL . 'socket_connect() a échoué adresse : ' . $this->adress . ':' . $this->port . ' raison : ' . socket_strerror(socket_last_error()) . PHP_EOL;
                return null;
            }
     
            if (!@socket_write($this->socket, $msg, strlen($msg))) {
                //echo PHP_EOL . __FILE__ . ':' . __LINE__ . PHP_EOL . PHP_EOL . 'socket_write() a échoué adresse : ' . $this->adress . ':' . $this->port . ' raison : ' . socket_strerror(socket_last_error()) . PHP_EOL;
            }
     
            socket_close($this->socket);
     
            return true;
        }
    }

  2. #2
    Membre éprouvé Avatar de Marc3001
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    829
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 829
    Points : 1 275
    Points
    1 275
    Par défaut
    Citation Envoyé par Bazou00 Voir le message
    J'ai réalisé des sockets php (client et serveur) mais je me heurte à un problème, lorsque dans mon onglet 1 j'attends des données, je ne peux pas écrire avec une nouvelle socket grâce à l'onglet 2.
    Citation Envoyé par Bazou00 Voir le message
    Par ailleurs, lorsque j'écoute mon serveur, dès que j'ai la réponse, je ferme ma connexion, ce n'est pas comme ceci que Stephane Eyskens fait, il affiche l'ip:port dans une frame, recupère le contenu d'avant et ajout le nouveau message.
    Ton code php s'éxécute sur le serveur web. A partir du moment où ta page est affichée sur ton navigateur, ton script a terminé toute son éxécution.

    Comment as-tu architecturé tes scripts? Quel morceaux dans quelle page? Lances-tu tous tes scripts via navigateur ou certains (serveur) via CLI?

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 17
    Points : 12
    Points
    12
    Par défaut
    Bonjour,

    Merci de t'intéresser à mon problème. Désolé pour la latence de la réponse, je pensais être notifié par mail.

    Je lance en CLI le code serveur (Cf. le premier paragraphe de code).

    J'ai trouvé une solution pour passer outre, mais elle n'est pas utilisable en prod.

    Voici une des applications des sockets :

    • J'ai une page avec ma liste des commandes
    • Une autre avec le détail de ma commande


    Elles sont chacune exécuté sur des postes client. Un commercial peut s'attribuer une commande, alors la liste des commandes doit s'actualiser sur tous les navigateurs l'affichant.

    Aujourd'hui, je stockes tous les messages avec l'ID de la commande et le nom du commercial, toutes les 1 secondes, ma socket va demander au serveur les messages et mets à jour les lignes de la liste des commandes.

    On perd pas mal l'intérêt de la mise à jour lorsqu'il y a une info.


    Le problème c'est que si j'attends l'info avec une boucle, cela empêche de mettre à jour le détail d'une commande.

    Ma liste boucle pour attendre l'info, tant qu'elle boucle, le même navigateur internet dans un onglet différent du poste client ne peut pas écrire au serveur.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Salut Bazou,

    Ta socket doit simplement accepter les connexions/opérations non bloquantes
    Et donc ton constructeur doit être

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public function __construct($adress, $port) {
            $this->adress = $adress;
            $this->port   = $port;
            $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
            socket_set_nonblock($socket);
            $this->socket = $socket;
    }
    Tu dois donc adapter l'écoute de chaque client

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     public function read()
        {
            if (!@socket_connect($this->socket, $this->adress, $this->port)) {
                echo PHP_EOL . __FILE__ . ':' . __LINE__ . PHP_EOL . PHP_EOL . 'socket_connect() a échoué adresse : ' . $this->adress . ':' . $this->port . ' raison : ' . socket_strerror(socket_last_error()) . PHP_EOL;
                return null;
            }
     
            socket_write($this->socket, $this->new, strlen($this->new));
     
            return ($data = socket_read($this->socket, $this->buffer));
        }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $socket = new Socket(SOCKET_SERVER, $_REQUEST['port']);
    if ($socket->read() === FALSE){
        //aucune donnee recue
    }
    else{
        //msgs recus
    }
    Et pour le refresh auto tu peux le faire via Javascript toutes les 10s sur chaque page cliente

    PS:
    Tu devrais avoir une classe abstraite Socket, une SocketClient, et une SocketServer.

    PS2:
    Ta conception du problème initial (Gestion de commandes client/fournisseur
    en gros) est vraiment à revoir. Une simple architecture utilisant une BD,
    ajax et PHP est proprement interessante/scalable/efficace.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 17
    Points : 12
    Points
    12
    Par défaut
    Le problème de le mettre les sockets en non bloquantes c'est que je ne reçois jamais les messages, car je fais lecture, clôture.

    Comment est-ce que je peux lire, rester connecté et lire quand même mon message arrive ? Tout en gardant la possibilité d'envoyer.

    • Car si je fais un while en lecture, je reçois la réponse, mais pendant ce temps, je ne peux pas écrire.
    • Si je refresh ma page, je perds mon instance de socket.


    Tu as raison pour la classe abstraite, je vais reprendre tout ça.

    Pour ce qui est de l'appel en BD, à la base, je voudrais mettre à jour les infos dès qu'elles arrivent, sans faire un refresh toutes les X secondes. Actuellement c'est une table en memory. Mais le système se développera et évoluera surement pour d'autres choses, je voudrais donc ne pas utiliser de settimeout et faire du push d'information (sans installer un serveur apache différent comme ape ou utiliser node.js).

  6. #6
    Invité
    Invité(e)
    Par défaut
    Si je refresh ma page, je perds mon instance de socket
    Dans Socket::read() les 3 1ères lignes s'occupent de se connecter
    (maladroitement d'ailleurs) à chaque tentative de lecture sur le serveur.

    Donc à chaque refresh en JS (coté CLIENT) tu as une nvelle demande de connexion et une nvelle tentative de lecture; Sans passer par une boucle active.


    je voudrais mettre à jour les infos dès qu'elles arrivent,
    sans faire un refresh toutes les X secondes
    Bah le principe même de l'http1.1 c'est de faire des Request et d'attendre des réponses. En utilisant une BD, un script de lecture (qui de renvoi les nouvelles entrées) et un peu d'Ajax, tu résouds ton problème et tu rends le refresh transparent aux yeux de l'user.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 17
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par foberken Voir le message
    (maladroitement d'ailleurs)
    Comment le faire adroitement ?

    Le problème d'un refresh c'est que si l'utilisateur ouvre 50 onglets, le serveur est bouché (car 50 appel toutes les X secondes), pour rien, car potentiellement il n'y a pas de nouvelle information.



    Ok pour le principe de l'HTTP, mais je veux étendre ce principe, au lieu d'avoir du poll :

    client -> serveur, donne moi les infos

    je veux du push :

    serveur -> tient client, voici les nouvelles infos.


    Cela est possible avec les sockets, puis que la socket master est capable de notifier tous les clients qui sont connectés. Si mes clients ne devaient pas lire ET écrire en même temps, tout irai bien.

  8. #8
    Membre éprouvé Avatar de Marc3001
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    829
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 829
    Points : 1 275
    Points
    1 275
    Par défaut
    Le gros souci que je trouve à ta solution c'est la connexion directe des clients à ton socket serveur.
    Certes tu as du vrai push mais ta solution nécessite une ouverture de flux directe du client vers le serveur sur le port du socket serveur.
    Donc nécessité d'ouverture firewall et utilisation d'un proxy compliquée.

    Le problème d'un refresh c'est que si l'utilisateur ouvre 50 onglets, le serveur est bouché (car 50 appel toutes les X secondes), pour rien, car potentiellement il n'y a pas de nouvelle information.
    Finalement ton socket serveur fait le même boulot qu'Apache à part que la connexion est permanente. Je pense réellement qu'Apache est largement optimisé pour gérer ces connexions et que si tu as de grosses sollicitations Apache tiendra mieux la charge que ton socket.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 17
    Points : 12
    Points
    12
    Par défaut
    Je ne veux pas refresh toutes les X secondes, se sera beaucoup trop lourd pour notre faible MySQL.



    Est-ce qu'il est possible d'avoir du temps réel ?
    Connais-tu un moyen ?
    Comment procèdent Facebook et GoogleDoc ?

  10. #10
    Membre éprouvé Avatar de Marc3001
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    829
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 829
    Points : 1 275
    Points
    1 275
    Par défaut
    Je suis presque sûr que google et facebook n'utilisent pas de socket mais bien de l'ajax avec du refresh toutes les x secondes.....

  11. #11
    Membre chevronné
    Avatar de la.lune
    Homme Profil pro
    Directeur Technique
    Inscrit en
    Décembre 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Comores

    Informations professionnelles :
    Activité : Directeur Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 545
    Points : 2 084
    Points
    2 084
    Par défaut
    Je suis dans des recherches sur cette question, le peu que je sais c'est que Facebook et Twitter utilisent des flux(des socket: car un socket n'est autre qu'un flux entre client et serveur) et même le PDG de facebook Zukergerd a critiqué que le flux de twitter quand l'utilisateur se déconnecte le flux n'est pas fermé automatiquement, ce qui fait qu'on peut lire des données contenu dans ce flux. Ce que je ne sais jusqu’à présent comment ils sont développé est ce des socket en pure langage C pour besoin de rapidité ou des socket en php ou des J2EE, je ne sais pas.

Discussions similaires

  1. Différence d'affichage d'un simple CSS avec un même navigateur
    Par Décibel dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 15/10/2014, 14h32
  2. Réponses: 5
    Dernier message: 07/06/2010, 11h49
  3. besoin d'aide usf:Lire & Ecrire avec Rechercher
    Par DRH01 dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 20/05/2010, 15h52
  4. Réponses: 3
    Dernier message: 22/07/2009, 19h09
  5. Lire et ecrire un fichier excel avec perl
    Par Bengeldim dans le forum Langage
    Réponses: 3
    Dernier message: 22/07/2008, 17h23

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