[LINUX] Programmation asynchrone avec libev # 2

Voici un exemple de client HTTP simple. S'il n'y a pas de problème de communication, le html de la première page de google sera affiché sur la console.

Veuillez consulter # 1 pour l'installation de libev.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string>
#include <ev.h>
#include <iostream>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#define SOCKET int
#define SD_BOTH SHUT_WR

#define READ_BUF_SIZE 4096
#define BUF_SIZE 4097
#define PORT 80

void close_socket(SOCKET socket){
    ::close(socket);
}

int get_error(){
    return errno;
}

//Connexion TCP.
SOCKET tcp_connect(const char* host){
    
    struct hostent *hp;
    struct sockaddr_in addr;
    SOCKET _socket;
    
    if (!(hp = gethostbyname(host))){
        return -1;
    }
    memset(&addr, 0, sizeof(addr));
    addr.sin_addr = *(struct in_addr*)hp->h_addr_list[0];
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    
    if ((_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))<0){
        return -1;
    }
    if (connect(_socket, (struct sockaddr *)&addr, sizeof(addr))<0){
        return -1;
    }
    
    //Défini sur non bloquant.
    int flag = fcntl(_socket, F_GETFL, 0);
    fcntl(_socket, F_SETFL, flag | O_NONBLOCK);
    
    return _socket;
}


static void io_cb (EV_P_ ev_io *w, int revents)
{
    char buf[BUF_SIZE] = { 0 };
    char* p = buf;
    int r = (int)::recv(w->fd, p, READ_BUF_SIZE, NULL);
    
    if(r > 0){
        std::cout << p;
    }
    
    
    //Commentez ce qui suit pour terminer avec un délai d'attente.
    
    // I/Dissocier O de la boucle.
    //ev_io_stop (EV_A_ w);
    
    //Briser la boucle des événements.
    //ev_unloop (EV_A_ EVUNLOOP_ALL);
}

static void timeout_cb (EV_P_ ev_timer *w, int revents)
{
    std::cout << "timeout\n";

    //Arrêtez le chronomètre.
    ev_timer_stop (EV_A_ w);
    
    //Briser la boucle des événements.
    ev_unloop (EV_A_ EVUNLOOP_ONE);
}

int main(int argc, const char * argv[])
{
    
    std::string host = "www.google.co.jp";
    
    SOCKET _socket = tcp_connect(host.c_str());

    
    //Créer une boucle d'événements.
    struct ev_loop *loop = ev_loop_new (0);

    // I/Ô objet de montre.
    ev_io io_watcher;
    
    // I/Pour les objets O watch
    //Associer des rappels aux FD avec des types d'événements.
    ev_io_init (&io_watcher, io_cb, _socket, EV_READ);
    
    // I/Associer une boucle d'événement à un objet O watch.
    ev_io_start (loop, &io_watcher);


    //Créer un objet minuterie.
    ev_timer timeout_watcher;
    
    //Associer un rappel à un objet timer et spécifier un timeout.
    ev_timer_init (&timeout_watcher, timeout_cb, 20, 0.);
    
    //Associer une boucle d'événements à un objet timer.
    ev_timer_start (loop, &timeout_watcher);
    
    
    std::string str = "GET / HTTP/1.1\r\nHost: " + host;
    str = str + "\r\n\r\n";
    int w = (int)::send(_socket, str.c_str(), str.length(), NULL);
    
    std::cout << "write count" << w << "\n";
    
    //Début de boucle.
    ev_loop (loop, 0);

    //Si vous ne voulez pas bloquer.
    //ev_loop (loop, EVLOOP_NONBLOCK);

    
    std::cout << "end\n";
    
    //Supprimer la boucle d'événements créée
    ev_loop_destroy(loop);
    
    close_socket(_socket);
    
    return 0;
}

La méthode de compilation est la suivante. Modifiez le chemin et la version de la bibliothèque.

gcc -o test test.cpp -lev -I/usr/local/Cellar/libev/4.15/include/ -L/usr/local/Cellar/libev/4.15/lib/ -lstdc++

Recommended Posts

Programmation asynchrone avec libev # 2
Programmation asynchrone avec libev
Programmation asynchrone avec libev # 3
3. 3. Programmation IA avec Python
Programmation Python avec Atom
Programmation compétitive avec python
Programmation Shader avec pyOpenGL
Programmation linéaire avec PuLP
Programmation avec Python Flask
Programmation avec Python et Tkinter
Essayez de programmer avec un shell!
Essayez la programmation GUI avec Hy
Jeu éducatif de programmation avec SenseHAT
Programmation réseau avec Python Scapy
[Python] Programmation orientée objet apprise avec Pokemon
Programmation facile Python + OpenCV avec Canopy
[Python] Requête asynchrone avec async / await
Programmation pour les humains avec un __repr__ bien défini
Programmation de compétition avec les paramètres de l'environnement local python
Programmation GUI à l'aide de kivy ~ Partie 4 Divers boutons ~
Compréhension complète de la programmation asynchrone Python
Programmation normale avec la programmation Node-RED avec Raspberry Pi 3
Faites de la programmation embarquée avec un développement piloté par les tests avec googletest
Programmation sonore avec Go (super niveau d'introduction)
Ce que vous pouvez faire avec des compétences en programmation