[LINUX] Asynchrone Programmierung mit libev # 2

Hier ist ein Beispiel für einen einfachen HTTP-Client. Wenn es kein Problem mit der Kommunikation gibt, wird das HTML der oberen Seite von Google auf der Konsole angezeigt.

Die Installation von libev finden Sie unter # 1.

#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;
}

//TCP-Verbindung.
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;
    }
    
    //Auf nicht blockierend einstellen.
    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;
    }
    
    
    //Kommentieren Sie Folgendes aus, um mit einer Zeitüberschreitung zu beenden.
    
    // I/Trennen Sie O von der Schleife.
    //ev_io_stop (EV_A_ w);
    
    //Unterbrechen Sie die Ereignisschleife.
    //ev_unloop (EV_A_ EVUNLOOP_ALL);
}

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

    //Stoppen Sie den Timer.
    ev_timer_stop (EV_A_ w);
    
    //Unterbrechen Sie die Ereignisschleife.
    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());

    
    //Erstellen Sie eine Ereignisschleife.
    struct ev_loop *loop = ev_loop_new (0);

    // I/O Objekt beobachten.
    ev_io io_watcher;
    
    // I/Für O Objekte beobachten
    //Verknüpfen Sie Rückrufe mit FDs mit Ereignistypen.
    ev_io_init (&io_watcher, io_cb, _socket, EV_READ);
    
    // I/Verknüpfen Sie eine Ereignisschleife mit einem O-Überwachungsobjekt.
    ev_io_start (loop, &io_watcher);


    //Erstellen Sie ein Timer-Objekt.
    ev_timer timeout_watcher;
    
    //Verknüpfen Sie einen Rückruf mit einem Zeitgeberobjekt und geben Sie eine Zeitüberschreitung an.
    ev_timer_init (&timeout_watcher, timeout_cb, 20, 0.);
    
    //Verknüpfen Sie eine Ereignisschleife mit einem Zeitgeberobjekt.
    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";
    
    //Schleifenstart.
    ev_loop (loop, 0);

    //Wenn Sie nicht blockieren möchten.
    //ev_loop (loop, EVLOOP_NONBLOCK);

    
    std::cout << "end\n";
    
    //Verwerfen Sie die erstellte Ereignisschleife
    ev_loop_destroy(loop);
    
    close_socket(_socket);
    
    return 0;
}

Die Kompilierungsmethode ist wie folgt. Ändern Sie den Pfad und die Version der Bibliothek.

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

Asynchrone Programmierung mit libev # 2
Asynchrone Programmierung mit libev
Asynchrone Programmierung mit libev # 3
3. 3. KI-Programmierung mit Python
Python-Programmierung mit Atom
Wettbewerbsfähige Programmierung mit Python
Shader-Programmierung mit pyOpenGL
Lineare Programmierung mit PuLP
Programmieren mit Python Flask
Programmieren mit Python und Tkinter
Versuchen Sie, mit einer Shell zu programmieren!
Versuchen Sie die GUI-Programmierung mit Hy
Programmier-Lernspiel mit SenseHAT
Netzwerkprogrammierung mit Python Scapy
[Python] Mit Pokemon erlernte objektorientierte Programmierung
Einfache Python + OpenCV-Programmierung mit Canopy
[Python] Asynchrone Anfrage mit async / await
Programmierung für Menschen mit einem genau definierten __repr__
Wettbewerbsprogrammierung mit Python Lokale Umgebungseinstellungen
GUI-Programmierung mit kivy ~ Teil 4 Verschiedene Tasten ~
Vollständiges Verständnis der asynchronen Python-Programmierung
Normal programmieren mit Node-RED-Programmierung mit Raspberry Pi 3
Führen Sie Embedded-Programmierung mit testgetriebener Entwicklung mit googletest durch
Soundprogrammierung mit Go (Super-Einführungslevel)
Was Sie mit Programmierkenntnissen machen können