아래 예제 코드는 간단한 에코 서버다.
스트레스 툴을 만들어서 십여개의 connexction을 생성한 후 일괄 close하면
메모리에러가 발생하면서 프로그램이 종료된다.
원인은 이벤트 구조체가 잘못된듯한다..
free부분을 제거하면 이러한 에러가 사라지기는 하지만 어떻게 그럴수가 있는가 -_-;;
결국 일주일간의 노력은 모두 물거품이 되어버렸다.
일단 멀티 스레드 서버로 프로젝트는 후다닥 진행해야겠다..
struct client {
struct event ev_read;
struct event ev_write;
int id;
};
int main(int argc, char **argv)
{
nametag = 0;
timer = 0;
Initialize();
Initialize_Net();
event_init();
event_priority_init(1);
memset(&ev_accept,0,sizeof(ev_accept));
event_set(&ev_accept, listen_sock, EV_READ | EV_PERSIST, on_accept, NULL);
event_add(&ev_accept, NULL);
StartQueryService();
event_dispatch();
WSACleanup();
return 0;
}
void on_accept(int fd, short ev, void *arg)
{
int client_fd;
struct sockaddr_in client_addr;
int client_len = sizeof(client_addr);
struct client *client;
/* Accept the new connection. */
client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len);
if (client_fd == -1) {
printf("accept failed");
return;
}
if (setnonblock(client_fd) < 0)
printf("failed to set client socket non-blocking");
client = (struct client *)calloc(1, sizeof(struct client));
client->id = i_client;
i_client++;
event_set(&client->ev_read, client_fd, EV_READ|EV_PERSIST, on_read, client);
event_add(&client->ev_read, NULL);
/* Create the write event, but don’t add it until we have
* something to write. */
event_set(&client->ev_write, client_fd, EV_WRITE, on_write, client);
/* Initialize the clients write queue. */
printf("Accepted connection from %s\n",
inet_ntoa(client_addr.sin_addr));
}
void on_write(int fd, short ev, void *arg)
{
struct client *client = (struct client *)arg;
struct bufferq *bufferq;
int len;
char buf[DEFAULT_RECV_LEN];
len = send(fd,buf,DEFAULT_RECV_LEN,0);
if (len == -1) {
if (errno == EINTR || errno == EAGAIN) {
event_add(&client->ev_write, NULL);
return;
}
else {
printf("send error\n");
}
}
printf("%d: %d byte send\n",client->id,len);
}
/**
* This function will be called by libevent when the client socket is
* ready for reading.
*/
void on_read(int fd, short ev, void *arg)
{
struct client *client = (struct client *)arg;
struct bufferq *bufferq;
char buf[DEFAULT_RECV_LEN];
int len;
len = recv(fd, buf, DEFAULT_RECV_LEN,0);
if (len == 0) // disconnected
{
printf("%d Client disconnected.\n",client->id);
closesocket(fd);
if (event_initialized(&client->ev_read))
{
if(event_del(&client->ev_read) == 0)
{
free(client);
client = NULL;
}
else
printf("event delete failed\n");
}
return;
}
else if (len < 0) // socket error :
{
printf("%d Socket failure, wsagetlasterror:%d \n",client->id,WSAGetLastError() );
closesocket(fd);
if (event_initialized(&client->ev_read))
{
if(event_del(&client->ev_read) == 0)
{
free(client);
client = NULL;
}
else
printf("event delete failed\n");
}
return;
}
printf("%d: %d byte recv\n",client->id,len);
event_add(&client->ev_write, NULL);
}