#include<sys/types.h>
#include<winsock2.h>
//#include<netinet/in.h> // for unix
#include<windows.h>
//#include<arpa/inet.h> // for unix
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
//#include<unistd.h> // for unix
#include<fcntl.h>
#include<errno.h>
#include<event.h>
#define SERV_PORT 8888
struct client
{
struct event ev_read;
};
int setnonblock(int fd)
{
/* // for unix
int flags;
flags = fcntl(fd, F_GETFL);
if(flags < 0)
{
return flags;
}
flags |= O_NONBLOCK;
if(fcntl(fd, F_SETFL, flags) < 0)
{
return -1;
}
*/
// for windows
u_long on = 1;
ioctlsocket(fd, FIONBIO, &on);
return 0;
}
void read_cb(int fd, short event, void *arg)
{
printf("read cb\n");
struct client *client = (struct client *)arg;
//u_char buf[8196];
char buf[8196];
int len, wlen;
memset(buf,0,8196);
len = recv(fd, buf, sizeof(buf),0);
if(len == 0)
{
printf("client disconnected\n");
closesocket(fd);
event_del(&client->ev_read);
free(client);
}
else if(len < 0)
{
printf("Socket failure, disconnecting client \n");
closesocket(fd);
event_del(&client->ev_read);
free(client);
}
else
{
printf("recv %d : %s\n",len,buf);
wlen = send(fd, buf, len,0);
if(wlen < len)
{
printf("Short write, not all data echoed back to client\n");
}
}
void accept_cb(int fd, short event, void *arg)
{
printf("accept cb\n");
int client_fd;
struct sockaddr_in client_addr;
int client_len = sizeof(client_addr);
struct client *client;
client_fd = accept(fd, (struct sockaddr *)&client_addr,
&client_len);
if(client_fd == -1)
{
return;
}
if(setnonblock(client_fd) < 0)
{
}
client = (struct client*)calloc(1, sizeof(*client));
if(client == NULL)
{
//err(1, "malloc failed");
}
event_set(&client->ev_read,
client_fd, EV_READ | EV_PERSIST ,
read_cb, client);
event_add(&client->ev_read, NULL);
printf("Accepted connection from %s\n",
inet_ntoa(client_addr.sin_addr));
}
int main(int argc, char **argv)
{
WSADATA data;
int sock;
struct sockaddr_in sa;
struct event ev;
int reuseaddr_on = 1;
WSAStartup(MAKEWORD(2,2), &data);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock==-1)
{
fprintf(stderr, "소켓 생성 오류\n");
return 0;
}
event_init();
memset(&sa, 0x00, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = INADDR_ANY;
sa.sin_port = htons(SERV_PORT);
if(setsockopt(sock,
SOL_SOCKET,
SO_REUSEADDR,
(char*)&reuseaddr_on,
sizeof(reuseaddr_on)) == -1)
{
printf("setsockopt error\n");
}
if ( -1 == bind(sock, (struct sockaddr*)&sa, sizeof(sa)) )
{
printf("소켓 바인드 오류\n");
return 0;
}
if ( -1 == listen(sock, 15) )
{
printf("소켓 리슨 오류\n");
return 0;
}
if(setnonblock(sock) < 0)
{
printf("set nonblocking error\n");
}
event_set(&ev,
sock,
EV_READ | EV_PERSIST,
accept_cb, NULL);
event_add(&ev, NULL);
event_dispatch();
return 0;
}
telnet으로 테스트했더니 잘 돌아간다...
어쨋든 참 생소한 방식이다..편하기도 하고..
이제 서버를 만들어야하는데...
이걸가기고 class를 만들까 그냥 C로 만들까..고민이다..
C++해본지도 오래됐는데.. class를 잘 만들수있을런지..
이번기회에 class로 잘 구성해 놓으면 두고두고 평생 잘 우려 먹을꺼같은데 ㅎㅎㅎㅎㅎ