[LINUX] Asynchronous programming with libev # 2

Here is an example of a simple HTTP client. If there is no problem with communication, the html of the top page of google will be displayed on the console.

Please see # 1 for installation of 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;
}

//TCP connection.
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;
    }
    
    //Set to non-blocking.
    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;
    }
    
    
    //Comment out the following to terminate with a timeout.
    
    // I/Disassociate O from loop.
    //ev_io_stop (EV_A_ w);
    
    //Break the event loop.
    //ev_unloop (EV_A_ EVUNLOOP_ALL);
}

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

    //Stop the timer.
    ev_timer_stop (EV_A_ w);
    
    //Break the event loop.
    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());

    
    //Create an event loop.
    struct ev_loop *loop = ev_loop_new (0);

    // I/O watch object.
    ev_io io_watcher;
    
    // I/For O watch objects
    //Associate callbacks with FDs with event types.
    ev_io_init (&io_watcher, io_cb, _socket, EV_READ);
    
    // I/Associate an event loop with an O watch object.
    ev_io_start (loop, &io_watcher);


    //Create a timer object.
    ev_timer timeout_watcher;
    
    //Associate a callback with a timer object and specify a timeout.
    ev_timer_init (&timeout_watcher, timeout_cb, 20, 0.);
    
    //Associate an event loop with a timer object.
    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";
    
    //Loop start.
    ev_loop (loop, 0);

    //If you don't want to block.
    //ev_loop (loop, EVLOOP_NONBLOCK);

    
    std::cout << "end\n";
    
    //Discard the created event loop
    ev_loop_destroy(loop);
    
    close_socket(_socket);
    
    return 0;
}

The compilation method is as follows. Change the library path and version yourself.

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

Asynchronous programming with libev # 2
Asynchronous programming with libev
Asynchronous programming with libev # 3
3. 3. AI programming with Python
Python programming with Atom
Competitive programming with python
Shader programming with pyOpenGL
Linear Programming with PuLP
Programming with Python Flask
Programming with Python and Tkinter
Try programming with a shell!
Try GUI programming with Hy
Programming education game with SenseHAT
Network programming with Python Scapy
[Python] Object-oriented programming learned with Pokemon
Easy Python + OpenCV programming with Canopy
[Python] Asynchronous request with async / await
Programming for humans with a well-defined __repr__
Competitive programming with python Local environment settings
GUI programming with kivy ~ Part 4 Various buttons ~
A complete understanding of Python's asynchronous programming
Programming normally with Node-RED programming on Raspberry Pi 3
Do embedded programming with test-driven development with googletest
Sound programming with Go (super introductory level)
What you can do with programming skills