在linux下 可以 通過 libevent 操作串口,完全當成一個網絡設備

在windows 下面不能實現 因爲 windows 的libevent 是針對 socket 的

linux下面是針對 設備 的 都能使用 poll 去查詢 他們的狀態

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <event2/event.h>
#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <netinet/tcp.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>

#include "lbvCom.h"

static void server_on_read(struct bufferevent* bev,void* arg){
    struct timeval start_t;
    gettimeofday(&start_t,NULL);
    printf("Warning: server_on_read start timestamp  %lu.%06lu\n", start_t.tv_sec, start_t.tv_usec);
 
    struct evbuffer* input = bufferevent_get_input(bev);
    size_t len = 0;
    len = evbuffer_get_length(input);
    printf("There Is %u Bytes Data In The Buffer In Total.\n",
            (unsigned)len);
    
    // read
    char* buf;
    buf = (char*)malloc(sizeof(char)*len);
    if(NULL==buf){return;}
    //evbuffer_copyout(input,buf,len); // it do not clear the input buffer
    evbuffer_remove(input,buf,len); // clear the buffer
    printf("Server gets the message from client: %s\n", buf);    
   
    // check
    len = 0;
    len = evbuffer_get_length(input);
    printf("After the first reading, there Is %u Bytes Data Left In The Buffer.\n",
            (unsigned)len);
    
    free(buf);
    buf=NULL;
    return;
}
 
 
void server_on_accept(struct evconnlistener* listener,evutil_socket_t fd,struct sockaddr *address,int socklen,void *arg)
{
    printf("accept a client : %d\n", fd);
 
    // set TCP_NODELAY
    int enable = 1;
    if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&enable, sizeof(enable)) < 0)
        printf("Consensus-side: TCP_NODELAY SETTING ERROR!\n");
 
    struct event_base *base = evconnlistener_get_base(listener);
    struct bufferevent* new_buff_event = bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE);
    // bufferevent_setwatermark(new_buff_event, EV_READ, 72, 0);
    bufferevent_setcb(new_buff_event,server_on_read,NULL,NULL,NULL);
    // set a read timeout of 1000 us
    // struct timeval tv = {0, 10000};
    // bufferevent_set_timeouts(new_buff_event, &tv, NULL);
    bufferevent_enable(new_buff_event,EV_READ|EV_WRITE);
 
    return;
}


void ReadComCb(evutil_socket_t fd, short flag, void *arg)
{
    int len;
    char buf[256];
    len = read(fd, buf, sizeof(buf)-1);buf[255]=0;
    if(len==0)
    {
        printf("no data!\r\n");
    }
    else
    {
        write(fd,buf,len);
        printf("rec:%s\r\n",buf);
    }
}


int main()
{
    int fdcom;
    struct sockaddr_in my_address;
    memset(&my_address, 0, sizeof(my_address));
    my_address.sin_family = AF_INET;
    my_address.sin_addr.s_addr = inet_addr("192.168.3.67");    //htonl(0x7f000001); // 127.0.0.1
    my_address.sin_port = htons(1920);
    struct event_base* base = event_base_new();
    struct evconnlistener* listener = 
        evconnlistener_new_bind(base,server_on_accept,
                NULL,LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,-1,
                (struct sockaddr*)&my_address,sizeof(my_address));
 
    if(!listener)
        exit(1);

    fdcom=OpenCom("/dev/ttyAMA1",115200L);
    if(fdcom==-1)
    {
        printf("open com fail\r\n");
        return -1;
    }
    else printf("open com ok%d\r\n",fdcom);

    struct event *ev=event_new(base,fdcom,EV_READ | EV_PERSIST, ReadComCb, (void*)fdcom);
    event_add(ev, NULL);

    event_base_dispatch(base);
    evconnlistener_free(listener);
    event_base_free(base);
 
    return 0;
}
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章