Отговори на тема  [ 11 мнения ] 
Препоръка за мултиплатформена socket библиотека (TCP/UDP)? 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Мар 13, 2006 12:59 pm
Мнения: 3855
Местоположение: Габрово
Мнение Препоръка за мултиплатформена socket библиотека (TCP/UDP)?
По аналогия с темата за GUI библиотеките, търся лека, малка C/C++ библиотека за работа с TCP и UDP сокети.
Изискванията са:
- поддръжка на линукс и win32 (BSD API и Windows sockets)
- да е лека в смисъла да има малко (или никакви) допълнителни зависимости
- да има асинхронно API - т.е. да има някакъв wrapper на select() и threading
- подходящ лиценз за комерсиален софтуер (статично свързан) - т.е. open source QT отпада (примерно MIT или BSD мисля че стават като лиценз)
- производителност не се търси, удобно API е много по-ценно, както и добра документация и примери

Гледах boost::asio и само asio, libevent и няколко други. Засега това най-ми допадна: http://sourceforge.net/projects/socketlibcpp/ но то не поддържа UDP.

Пример за евентуална таргет платформа е openwrt. Т.е. един от тестовите варианти ще е за такава система.


Пон Юли 21, 2014 10:03 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 5:52 pm
Мнения: 10355
Местоположение: Добрич
Мнение Re: Препоръка за мултиплатформена socket библиотека (TCP/UDP
а ти ли ще си я портваш?

ако да, то най-доброто решение се казва lwIP ;-)


Пон Юли 21, 2014 10:11 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 10:53 pm
Мнения: 4174
Местоположение: Brussels / Пловдив
Мнение Re: Препоръка за мултиплатформена socket библиотека (TCP/UDP
В момента работя с libevent ... става. Подкарах я без проблем под OpenWRT. Ако се спреш на нея ще ти дам едно рамо ако запъне някъде ...

едит: lwIP също става, но там нещо API-то и особенно сорсовете хич не ми паснаха на темперамента :D

_________________
Мразя да мразя ...


Пон Юли 21, 2014 12:12 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Мар 13, 2006 12:59 pm
Мнения: 3855
Местоположение: Габрово
Мнение Re: Препоръка за мултиплатформена socket библиотека (TCP/UDP
Май ще е libevent-a - ще питам ако възникнат въпроси, благодаря.
Видях че има алтернатива - libev. Имаш ли впечатления?


Пон Юли 21, 2014 4:51 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 10:53 pm
Мнения: 4174
Местоположение: Brussels / Пловдив
Мнение Re: Препоръка за мултиплатформена socket библиотека (TCP/UDP
Гледах го и него - изглежда същото като фунцкионалност. Доколкото успях да схвана преди време libevent е имал разни трески за дялане които са провокирали автора на libev да го направи - но това е било преди ... сега libevent се е развил и се ползва в една камара сериозни проекти докато libev е по слабо разпостранено. Та поне за мен везните натежаха заради по голямата юзер база на libevent т.е. повече инфо как се ползва, по стабилно и т.н. Честно казано ползвал съм го само за един проект и откак съм го интегрирал не съм имал никаква причина да го пипам - работи си като пушка.

В момента се заигравам с node.js - за ембедед платформи идва малко тежичко, ама с развитието на хардуера последните няколко години не е кой знае колко голям проблем да се подкара на някоя платка от рода на олимексиното или бигълбоне блек и т.н. - без да имам никаква идея що е то javascript успях за няколко часа да подкарам комуникация със устройството където ползвам libevent - сорса е няма и 100 линии ...

_________________
Мразя да мразя ...


Пон Юли 21, 2014 5:07 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Мар 13, 2006 12:59 pm
Мнения: 3855
Местоположение: Габрово
Мнение Re: Препоръка за мултиплатформена socket библиотека (TCP/UDP
Точно и node.js ми се въртеше в главата да погледна за тази задача, но само ц/ц++ минава.
Имаш ли някакви референции към приложения или примери с libevent, който да са подходящи за запознаване и "копиране" на идеи?


Пон Юли 21, 2014 10:35 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 10:53 pm
Мнения: 4174
Местоположение: Brussels / Пловдив
Мнение Re: Препоръка за мултиплатформена socket библиотека (TCP/UDP
Доколкото помня намерих доста примери с гугле - виж и моя код де, тривиално е:

Код:
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include <unistd.h>
#include <string.h>

#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/thread.h>

#include <pthread.h>
struct partial_read
{
    uint8_t *   buffer;
    size_t      total;
    size_t      current;
};

inline
void partial_read_init(struct partial_read * const pr, uint8_t * const buffer, const size_t total)
{
    pr->buffer  = buffer;
    pr->total   = total;
    pr->current = 0;
}

inline
bool partial_read_done(struct partial_read const * const pr)
{
    return pr->current == pr->total;
}

inline
size_t partial_read_left(struct partial_read const * const pr)
{
    return pr->total - pr->current;
}

inline
uint8_t * const partial_read_at(struct partial_read const * const pr)
{
    return &pr->buffer[pr->current];
}

inline
void partial_read_append(struct partial_read * const pr, size_t append)
{
    pr->current += append;
}

enum message_type
{   
    MT_PING     = 0x00,
    MT_DELETE   = 0x01,
};

struct message_header
{
    uint8_t type;
};

struct message_delete
{
    uint32_t message_id;
};

static struct message_header    header;
static struct partial_read      header_reader;

static struct message_delete    delete;
static struct partial_read      delete_reader;

static bool bufferevent_input_empty(struct bufferevent *bev)
{
    return evbuffer_get_length(bufferevent_get_input(bev))==0;
}

static
bool bufferevent_partial_read(struct bufferevent *bev, struct partial_read *pr)
{
    while(!partial_read_done(pr))
    {
        if(bufferevent_input_empty(bev))
            return false;

        partial_read_append(pr,
                bufferevent_read(bev, partial_read_at(pr),
                    partial_read_left(pr)));
    }

    return true;
}

static
void communication_readers_init(void)
{
    LOG_ERROR("Preparing to receive new command");

    partial_read_init(&header_reader, (uint8_t *)&header, sizeof(header));
    partial_read_init(&delete_reader, (uint8_t *)&delete, sizeof(delete));
}

static
void read_cb(struct bufferevent *bev, void *ctx)
{
    LOG_ERROR("Receiving data");

    if(!bufferevent_partial_read(bev, &header_reader))
        return;

    switch(header.type)
    {
        case MT_PING:
            LOG_ERROR("PING");
            /* TODO: Add TIMEOUT to close connection if there is no PING for a while */
            break;

        case MT_DELETE:
            if(!bufferevent_partial_read(bev, &delete_reader))
                return;

            LOG_ERROR("DELETE");

            // event_delete(delete.message_id);
            break;

        default:
            LOG_ERROR("Unknown command %02X", header.type);
            event_base_loopexit(bufferevent_get_base(bev), NULL);
            return;
    }

    communication_readers_init();
}

static
struct bufferevent *bev;

static
void event_cb(struct bufferevent *unused_bev, short events, void *ctx)
{
    unused_bev = unused_bev;

    if(events & BEV_EVENT_ERROR)
        LOG_ERRNO("Error from bufferevent");

    LOG_ERROR("Got an event");

    if(events & (BEV_EVENT_ERROR | BEV_EVENT_EOF))
    {
        bufferevent_free(bev); bev=NULL;
    }
}

static
void accept_cb(struct evconnlistener *listener,
        evutil_socket_t fd, struct sockaddr* address, int addr_len,
        void *ctx)
{
    LOG_ERROR("Accepting connection");

    struct event_base *base = evconnlistener_get_base(listener);
    bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);

    bufferevent_setcb(bev, read_cb, NULL, event_cb, NULL);
    bufferevent_enable(bev, EV_READ|EV_WRITE);
}

static
void error_cb(struct evconnlistener *listener,
        void *ctx)
{
    struct event_base *base = evconnlistener_get_base(listener);

    LOG_ERRNO("Got an error on listener");

    event_base_loopexit(base, NULL);
}

void communication_run_once(void)
{
    struct  event_base     *base;
    struct  sockaddr_in     sock_addr;
    struct  evconnlistener *listener;

    LOG_ERROR("Starting communication session");

    communication_readers_init();

    /* event base */
    base = event_base_new();
    if(!base) { LOG_ERROR("Couldn't create event base"); return; }

    /* listener address and port */
    sock_addr.sin_family        = AF_INET;
    sock_addr.sin_addr.s_addr   = htonl(0);
    sock_addr.sin_port          = htons(0x5246);

    /* listener */
    listener = evconnlistener_new_bind(base, accept_cb, NULL,
            LEV_OPT_THREADSAFE|LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1,
            (struct sockaddr*)&sock_addr, sizeof(sock_addr));
    if(listener==NULL) { LOG_ERRNO("Couldn't create listener"); goto free_base; }

    evconnlistener_set_error_cb(listener, error_cb);

    LOG_ERROR("Calling event base dispatch");
    /* dispatch */
    event_base_dispatch(base);

    LOG_ERROR("event base dispatch is done");

    /* exit & clean up */
    if(bev!=NULL) {  bufferevent_free(bev); bev=NULL; }
/* free_listener: */
    evconnlistener_free(listener);
free_base:
    event_base_free(base);
}

void *communication_run(void *ctx)
{
    UNUSED(ctx);

    LOG_ERROR("Starting communication thread");

    for(;;)
        communication_run_once();
}

int main(int argc, char ** argv)
{
    UNUSED(argc); UNUSED(argv);
    pthread_t communication_thread, rfid_thread;

    LOG_ERROR("Starting application");

    evthread_use_pthreads();

    pthread_create(&communication_thread, NULL, communication_run, NULL);
    pthread_create(         &rfid_thread, NULL,          rfid_run, NULL);

    void *status;
    pthread_join(rfid_thread, &status);

    return 0;
}


Дотук е за приемане - малко по сложно е отколкото може да се напише но целта ми беше да е ясно след години кое какво прави ;)
Изпращането на данни по сокета е супер просто:

Код:
void tags_send(const Tags* const tag)
{
    if(bev!=NULL)
        bufferevent_write(bev, &tag->epc, sizeof(tag->epc));
}


Поизрязах кода който няма отношение към libevent - тествано е, работи - може директно да го преправиш до каквото ти трябва ...

_________________
Мразя да мразя ...


Пон Юли 21, 2014 11:25 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 10:53 pm
Мнения: 4174
Местоположение: Brussels / Пловдив
Мнение Re: Препоръка за мултиплатформена socket библиотека (TCP/UDP
И виж само за куриоз node.js кода който комуникира колко е по кратък:
Код:
var dissolve = require("dissolve");
var net = require("net");

var rfidAntenna = function (id, url) {

    var self = this;

    var log_id = "Antenna #"+id+"("+url+") ";

    var parser = dissolve().loop(function(end) {
        this.buffer("epc",32).tap(function(){
            this.push(this.vars);
            this.vars = {};
        });
    });

    parser.on("readable", function() {
        var e;
        while( e = parser.read()) {
            self.emit("read", {
                date: new Date(),
                epc:e.epc });
        }
    });

    var socket = net.Socket();
    var socket_connected = false;
    var need_reconnect = false;

    var timer = null;

    var reconnect = function() {
        need_reconnect = false;

        if(timer) {
            clearInterval(timer);
            timer = null;
        }

        socket = net.Socket();
        socket.setKeepAlive(true);
        socket.connect(0x5246, url);

        socket.on("data", function(d){
            parser.write(d);
        });

        socket.on("end", function() {
            need_reconnect = true;
            if(socket_connected) {
                console.log(log_id+"socket closed - reconnecting ...");
                socket_connected = false;
            }
        });

        socket.on("error", function() {
            need_reconnect = true;
            if(socket_connected) {
                console.log(log_id+"socket error - reconnecting ...");
                socket_connected = false;
            }
        });

        socket.on("connect", function() {
            console.log(log_id+"socket connected");
            socket_connected = true;
        });

        /* emulate keepalive once per second */
        timer = setInterval(function() {
            if(need_reconnect) {
                reconnect();
            } else if(socket_connected) {
                socket.write("00","hex");
            }
        }, 1000);
    };

    reconnect();
}

rfidAntenna.prototype = Object.create(require('events').EventEmitter.prototype);
module.exports = rfidAntenna;


Това което не ми харсва е, че след време най вероятно ще се затрудня да го разбера какво точно прави и защо работи - бързо писане, трудна поддръжка след време ... виж на C е по бавно писане, но пък по евтина поддръжка по нататък ...

_________________
Мразя да мразя ...


Пон Юли 21, 2014 11:33 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Мар 13, 2006 12:59 pm
Мнения: 3855
Местоположение: Габрово
Мнение Re: Препоръка за мултиплатформена socket библиотека (TCP/UDP
Благодаря! Изглежда идеално за начало.


Вто Юли 22, 2014 7:47 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 12:58 pm
Мнения: 4580
Местоположение: US
Мнение Re: Препоръка за мултиплатформена socket библиотека (TCP/UDP
Qt :-) , не е малка, нито пък лека, но каквото съм написал на Qt го пускам без преработка на Windows/Linux. Сега вече има и Android, но още не съм го пробвал.

_________________
Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....


Съб Авг 02, 2014 1:29 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Мар 13, 2006 12:59 pm
Мнения: 3855
Местоположение: Габрово
Мнение Re: Препоръка за мултиплатформена socket библиотека (TCP/UDP
Много е голямо qt-то - само core-а е няколко мегабайта. На някой от устройствата го има качено, но на други го няма и не мога да го качвам.
Мисля че лиценза на open source варианта не позволява статично линкване, иначе това би било идеалния вариант?


Вто Авг 05, 2014 6:27 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 11 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 2 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни