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
[email protected]
http://monkey.org/mailman/listinfo/libevent-users