hi,all
        i am a newbie to libevent.
        i use libevent to build my application's network framework. it works
well. but  there are still some questions about it.
        data reading from network work very well.
        but data i want to write to network are not very reliable  when
about 200 clients connect to my server.
        i write data to client using method "bufferevent_write" , but
sometimes clients get  the data after 7 or 8 seconds.
        here are my main code, any suggestion are regarded. thank you!

========my code===========

int server_socket(int port)
{
        int sfd;
        struct linger ling = {0, 0};
        struct sockaddr_in addr;
        int flags =1;

        if ((sfd = new_socket()) == -1) {
            return -1;
        }

        setsockopt(sfd, SOL_SOCKET,  SO_REUSEADDR, &flags, sizeof(flags));
        setsockopt(sfd, SOL_SOCKET,  SO_KEEPALIVE, &flags, sizeof(flags));
        setsockopt(sfd, SOL_SOCKET,  SO_LINGER,    &ling,  sizeof(ling));
        setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY,  &flags, sizeof(flags));

        memset(&addr, 0, sizeof(addr));

        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
        if (bind(sfd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
                code_log_syslog(LOG_DEBUG,"[error]bind()");
                close(sfd);
                return -1;
        }
        if (listen(sfd, MAXLISTENQUEUE) == -1) {
                code_log_syslog(LOG_DEBUG,"[error]listen()");
                close(sfd);
                return -1;
        }
        return sfd;
}

int new_socket(void)
{
        int sfd;
        int flags;

        if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                code_log_syslog(LOG_DEBUG,"[error]socket()");
                return -1;
        }

        if ((flags = fcntl(sfd, F_GETFL, 0)) < 0 ||
                fcntl(sfd, F_SETFL, flags | O_NONBLOCK) < 0) {
                code_log_syslog(LOG_DEBUG,"[error]setting O_NONBLOCK");
                close(sfd);
                return -1;
        }
        return sfd;
}

void my_own_biz_code(char* PubBuf,int len)
{
        // proceed  data
        // some  biz  code ... ...
        
        //p_send_str=... ...
        
        // then  write  to client
        struct client_session* cs = csFindObj();
        if(cs==NULL)
        {
        
code_log_syslog(LOG_DEBUG,"[write_to_client]fd=[-1],content=[%s]",p_send_str
);
                return -1;
        }
        
code_log_syslog(LOG_DEBUG,"[write_to_client]fd=[%d],content=[%s]",cs->fd,p_s
end_str);
        
        //**************attention**********//
        //sometimes    not  very  reliable
        //sometimes  clients  get  data  very  slowly  when   200  clients
connected...
        //Are my usage of bufferevent_write correct??  somebody  help  me .
        
        bufferevent_enable(cs->bev, EV_WRITE);
        bufferevent_write(cs->bev,(void*)p_send_str,len);       
        return 0;
}

void code_readcb(struct bufferevent *bev, void *arg)
{
        ++CountNum;
        struct evbuffer* buffer=EVBUFFER_INPUT(bev);
        char* buf=(char*)EVBUFFER_DATA(buffer);
        size_t len = EVBUFFER_LENGTH(buffer);
        memset(PubBuf,0,10240);
        memcpy(PubBuf,buf,len);
        
code_log_syslog(LOG_DEBUG,"[readcb_read11]fd=[%d]count=[%d]buf=[%s]",bev->ev
_read.ev_fd,CountNum,PubBuf);
        
        //my own biz code
        //read  data  from  network  and  send  it  to  uplevel  code
        //this  works  very  well
        my_own_biz_code(PubBuf,len);
        
        evbuffer_drain(buffer,len);
}

void code_writecb(struct bufferevent *bev, void *arg)
{
        //nothing  to  be  done
}

void code_errorcb(struct bufferevent *bev, short what, void *arg)
{
        struct evbuffer *buffer = EVBUFFER_OUTPUT(bev);
        code_log_syslog(LOG_DEBUG, "[errorcb]fd=[%d]%s: called with %p,
freeing",bev->ev_read.ev_fd , __func__, arg);

        code_cs_free(arg);
}

void code_cs_free(void *arg)
{
        struct client_session* cs = (struct client_session*)arg;
        bufferevent_free(cs->bev);
        close(cs->fd);
        free(cs);
}

void connection_accept(int fd, short event, void *arg)
{
        int exit = 0;
        int connfd, flags = 1;
        socklen_t addrlen;
        struct sockaddr addr;
        addrlen = sizeof(addr);
        struct client_session *cs = (struct
client_session*)calloc(1,sizeof(struct client_session));
        if (cs == NULL){
                code_log_syslog(LOG_DEBUG, "[error]%s: out of memory\n",
__func__);
                return;
        }
        
        while (!exit) {
                addrlen = sizeof(addr);
                if ((connfd = accept(fd, &addr, &addrlen)) == -1) {
                        if (errno == EAGAIN || errno == EWOULDBLOCK) {
                                exit = 1;
                                continue;
                        } else {
        
code_log_syslog(LOG_DEBUG,"[error]accept()");
                        }
                        continue;
                }
                if ((flags = fcntl(connfd, F_GETFL, 0)) < 0 || fcntl(connfd,
F_SETFL, flags | O_NONBLOCK) < 0) {
                        code_log_syslog(LOG_DEBUG,"[error]setting
O_NONBLOCK");
                        close(connfd);
                        continue;
                }

                cs->fd=connfd;
                cs->bev = bufferevent_new(connfd,code_readcb, code_writecb,
code_errorcb, cs);
                if (cs->bev == NULL)
                        goto error;
                code_log_syslog(LOG_DEBUG,"[ACCEPT]accetp new conn:
fd=[%d]",connfd);
                bufferevent_enable(cs->bev, EV_READ | EV_WRITE);
                return;
        }
        
error:
        if (cs != NULL)
                free(cs);
        code_log_syslog(LOG_DEBUG, "[error]%s: out of memory\n", __func__);
        close(connfd);
}

int main(void)
{
        int clientfd;

        clientfd=server_socket(8000);

        event_init();
        struct event  ev_accept_client;
        event_set(&ev_accept_client, clientfd, EV_READ | EV_PERSIST,
connection_accept, NULL);
        event_priority_set(&ev_accept_client, 0);
        event_add(&ev_accept_client, NULL);
        event_dispatch();
}

========my code===========

_______________________________________________
Libevent-users mailing list
Libevent-users@monkey.org
http://monkey.org/mailman/listinfo/libevent-users

Reply via email to