¼ÒÄÏ°ü·ÃµÈ ÀϵéÀ» Æ÷°ýÇÏ´Â
?TEpollSocket class Á¦ÀÛÇØ º¸ÀÚ. ¸ñÇ¥´Â »ç¿ëÀÚ(Áï, ÀÌ Å¬·¡½º¸¦ ÀÌ¿ëÇؼ ¼¹ö©»ç¶÷)°¡ ¾ÆÁÖ ÀÌ¿ëÇϱâ ÆíÇϵµ·Ï ÇÏÀÚ´Â °Í.
- 1 Ŭ·¡½º ¼³°è °í¹Î = »ðÁú --;
- 2 ±¸ÇöÀÇ ¼ø¼
- 3 ±¸Çö#1 : »ç¿ëÀÚ ÀÔÀå¿¡¼ ¸ÕÀú º¸ÀÚ
- 3.1 main()ºÎÅÍ º¸ÀÚ
- 3.2 ?TEpollClient ?
- 3.3 ?TClient : public ?TEpollClient ±¸Çö
- 4 ±¸Çö #2 : ?TEpollSocketÀÇ ±¸Çö
- 4.1 template Àû¿ë
- 4.2 Sources / ?EpSocket ver 1.0
- 5 ÀÌÈÄÀÇ ±¸Çö°èȹ
1 Ŭ·¡½º ¼³°è °í¹Î = »ðÁú --; #
¸çÄ¥µ¿¾È °í¹ÎÀ» ÇßÀ½. °í¹ÎÀÇ ¼ø¼¸¦ ¤¾îº¸ÀÚ.
- main ÇÁ·Î±×·¡¸Ó°¡ °æÇèÀÌ ÀÖ°í ÀÀ¿ë·ÂÀÌ ÀÖ´Ù¸é, »ùÇà ¼Ò½º¸¸ º¸°í ¾ó¸¶µçÁö © ¼ö ÀÖÀ»ÅÙµ¥ ±¸Å¿© ¿Ö? ... ±×·¸Áö¸¸ ¹º°¡ ÂóÂóÇÏ´Ù.
- Client Ŭ·¡½º±îÁö ¸¸µé¾îÁà¹ö¸®°í, SocketŬ·¡½º°¡ Ŭ¶óÀ̾ðÆ® »ý¼º, ¼Ò¸ê±îÁö ¾Ë¾Æ¼ ´Ù Çعö¸®µµ·Ï ÇÏÀÚ. ¾ÆÁÖ ±ò²ûÇÏ°í ÆíÇÏ´Ù (ÀÎÅͳݿ¡ µ¹¾Æ´Ù´Ï´Â c++¼Ò½ºµéµµ ´ëºÎºÐ ÀÌ·± °ñ°ÝÀÌ´Ù). ÇÏÁö¸¸ Client Ŭ·¡½º°¡ º¹ÀâÇØÁú¼ö·Ï ÀÌ ±¸Á¶´Â ²ûÂïÇÒ µí ÇÏ´Ù. °Ô´Ù°¡ epoll ÇÔ¼öµéµµ ²ø°í ´ó°Ü¾ß ÇÑ´Ù. µ¶¸³¸ðµâ·Î ºÐ¸®ÇÒ ¼ö°¡ ¾ø´Ù.
- ¼ÒÄÏÀ̺¥Æ®¿¡ ÄݹéÇÔ¼ö¸¦ ¿¬°á½ÃÅ°ÀÚ!! ¼ÒÄϵ鿡¼ ¹«½¼ÀÏÀÌ »ý±â¸é ³»°¡ ¸¸µç ÇÔ¼ö°¡ È£ÃâµÇµµ·Ï ±¸¼ºÇÑ´Ù. ?CSock µîÀÌ ÀÌ·±¹æ½ÄÀ» ÃëÇÏ°í ÀÖ´Ù. ÇÏÁö¸¸ ÇÔ¼öÀÇ Æ÷ÀÎÅÍ ´Ù·ç±â°¡ ¸¸¸¸Ä¡ ¾Ê´Ù. ¿©·¯ Á¾·ùÀÇ ClientµéÀÌ Á¸ÀçÇÒ °æ¿ì¿¡ ÇÁ·Î±×·¥Àº À̷縻ÇÒ ¼ö ¾øÀÌ º¹ÀâÇØÁø´Ù.
- ÁÁ´Ù! template¸¦ ÀÌ¿ëÇÏÀÚ. ?BasicClient Ŭ·¡½º¸¦ Á¦°øÇØÁÖ°í »ç¿ëÀÚ·Î ÇÏ¿©±Ý ÀÌ°ÍÀ» »ó¼Ó¹Þ¾Æ ¸Ú´ë·Î Ŭ·¡½º¸¦ ¸¸µéµµ·Ï ÇÏ°í, ÀÌ·± Ä¿½ºÅ͸¶ÀÌ¡µÈ Client Ŭ·¡½º¸¦ ÆĶó¹ÌÅÍ·Î ÇÏ´Â template socket class ¸¦ ¸¸µéÀÚ!!
»ý°¢ÀÌ 4¹ø±îÁö Çϴµ¿¾È ½ÇÁ¦·Î À̰͵éÀ» ±¸ÇöÇغ¸¸é¼ ¼Ò½º¸¦ 100¹øµµ ³Ñ°Ô ¼öÁ¤ÇÏ°í °³¼±ÇÏ¿´´Ù. ÀÌ
?TEpollSocket Ŭ·¡½º¸¦ ÀÌ¿ëÇؼ äÆü¹ö´Â ¹°·Ð »ó¾÷Àû ¿Â¶óÀΰÔÀÓ±îÁö ±¸ÇöÀÌ °¡´ÉÇϵµ·Ï ¸¹Àº »ý°¢À» ÇØ ³»¾ß¸¸ Çß´Ù.
¹°·Ð ´õ ³ªÀº ¼³°è°¡ °¡´ÉÇÏ´Ù¸é, ¾ðÁ¦µçÁö Á¶¾ðÀ» ... !!
- ¸ÕÀú template ¾øÀÌ ±âº»¼ÒÄÏŬ¶óÀ̾ðÆ® Ŭ·¡½º ?TEpollClient ±¸Çö
- ¸¶Âù°¡Áö·Î template ¾øÀÌ ±âº» ¼ÒÄÏ Å¬·¡½º ?TEpollClass ±¸Çö
- µ¿ÀÛ Å×½ºÆ® - ¿ª½Ã echo ¼¹ö --;
- ¼ÒÄÏŬ·¡½º ?TEpollClassÀÇ Client Ŭ·¡½º¸¦ ÅÆÇø´À¸·Î ±¸Çö
- ¸¶Âù°¡Áö·Î, ?TEpollClient¸¦ »ó¼ÓÇÑ ³ªÀÇ Å¬·¡½º ?TClient ±¸Çö
- µ¿ÀÛ Å×½ºÆ® - echo ¼¹ö ¿Ï¼º !!
3 ±¸Çö#1 : »ç¿ëÀÚ ÀÔÀå¿¡¼ ¸ÕÀú º¸ÀÚ #
3.1 main()ºÎÅÍ º¸ÀÚ #
int main(void)
{
int n;
TEpollSocket<TClient> esock(MAX_CLIENT);
esock.Listen(8000);
for(;;){
esock.Do(10);
}
}
?TEpollSocketÀ¸·Î esock À̶ó´Â °´Ã¼¸¦ »ý¼ºÇߴµ¥, ÃʱⰪÀ¸·Î ¸î°³ÀÇ µ¿½ÃÁ¢¼ÓÀ» ó¸®ÇÒ °ÍÀΰ¡¸¦ Á¤Çϵµ·Ï ÇÏ°í ÀÖ´Ù. template·Î
?TClient¸¦ ÁöÁ¤Çϵµ·Ï ÇÏ¿´´Âµ¥, ÀÌ Å¬·¡½º´Â
?TEpollClient¸¦ »ó¼Ó¹Þ¾Æ
»ç¿ëÀÚ°¡ ¸¸µç Ŭ·¡½ºÀÌ´Ù.
3.2 ?TEpollClient ? #
class TEpollClient
{
protected :
int fd;
char addr[MAX_ADDR];
public :
TEpollClient(const int fd, const char *addr)
{
this->fd = fd;
strcpy(this->addr, addr);
};
virtual int OnRead(void) = NULL;
virtual int OnWrite(void) = NULL;
virtual int OnError(const int nerror) = NULL;
};
pure virtual 3°³¸¦ °¡Áö°íÀÖ´Â Æò¹üÇÑ class ÀÌ´Ù. ¹°·Ð ¼ø¼ö°¡»óÇÔ¼ö´Â ´ç½ÅÀÌ ±¸ÇöÇØ¾ß ÇÑ´Ù.
3.3 ?TClient : public ?TEpollClient ±¸Çö #
class TClient : public TEpollClient
{
public :
TClient(const int lfd, const char *laddr) : TEpollClient(lfd, laddr)
{
// Ãʱâȶ§ Ãß°¡ÀûÀ¸·Î ÇØÁÖ°í½ÍÀº ÀϵéÀÌ ÀÖ´Ù¸é ¿©±â¿¡ ...
};
virtual int OnRead(void);
virtual int OnWrite(void);
virtual int OnError(const int nerror);
};
¼±¾ð ÀÚü´Â Ưº°ÇÑ °ÍÀº ¾ø°í, »ý¼ºÀÚ¿¡¼ ºÎ¸ðŬ·¡½ºÀÎ
?TEpollClient¸¦ ±×³É ¹Ù·Î ÄÝ Çϵµ·Ï ÇÏ¿´´Ù. ¿ª½Ã 3°³ÀÇ virtual ÇÔ¼öµé ¼±¾ðÀ» ÇØÁÖ¾ú°í ¾Æ·¡¿¡ ±¸ÇöÇÏ¿´´Ù. echo ¼¹öÀ̹ǷΠµé¾î¿Âµ¥ÀÌÅ͸¦ ±×´ë·Î ½ð´Ù --;
// TEpollSocket.h ¿¡ ¼±¾ð
#define EP_ERROR_NONE 1
#define EP_ERROR_READ_CLOSE 0
#define EP_ERROR_READ_GEN -1
#define EP_ERROR_WRITE_GEN -2
// »ç¿ëÀÚ ±¸ÇöºÎºÐ
// 0 ÀÌÇÏÀÇ °ªÀ» ¸®ÅÏÇϸé, ¸®ÅÏ°ªÀÌ ±×´ë·Î OnError·Î Àü´ÞµÈ´Ù. ½ÇÁ¦ ¿¡·¯Ã³¸®´Â OnError¿¡¼...
int TClient::OnRead(void)
{
char buf[1024];
int nread, nwrite;
nread = read(fd, buf, 1024);
if(nread == 0) return EP_ERROR_READ_CLOSE;
else if(nread < 0) return EP_ERROR_READ_GEN;
// »ùÇÃÀ̶ó ÀÌ°÷¿¡ ±×³É ¹Ù·Î echo Çϵµ·Ï Çß´Ù.
nwrite = write(fd, buf, nread);
if(nwrite < 1) return EP_ERROR_WRITE_GEN;
return EP_ERROR_NONE;
};
// 0 ÀÌÇÏÀÇ °ªÀ» ¸®ÅÏÇϸé, ¸®ÅÏ°ªÀÌ ±×´ë·Î OnError·Î Àü´ÞµÈ´Ù
int TClient::OnWrite(void)
{
// ³ªÁß¿¡ SendBuffering ¹æ½ÄÀ¸·Î °íÄ¥°ÍÀ̸ç, ÀÌ °÷¿¡¼ ½ÇÁ¦ flush¸¦ ÇØÁÖ¾î¾ß ÇÑ´Ù.
return EP_ERROR_NONE;
};
int TClient::OnError(const int nerror)
{
// Áö±ÝÀº ¾Æ¹«Ã³¸®µµ ¾Ê°í ±×³É ¸®ÅÏÇÑ´Ù. TEpollSocketÀÌ ¾Ë¾Æ¼ ó¸®ÇÒ °ÍÀÌ´Ù ;)
cout << "Error detected : code %d\n";
return nerror;
};
?OnRead¿¡¼´Â ±×³É ÀÐ¾î¼ ´Ù½Ã ½÷ÁÖµµ·Ï °£´ÜÈ÷ ÀÛ¼ºÇß´Ù. read ÄÝÀÇ °á°ú°ªÀÌ 1º¸´Ù ÀÛÀ» °æ¿ì(Áï, 0 ÀÌÇÏÀΰæ¿ì)´Â ÀÌÈÄ Ã³¸®¸¦ ÇÏÁö ¾Ê°í ¹Ù·Î ¸®ÅÏÇϵµ·Ï Çߴµ¥ ¿¬°áÀÌ ²÷°å°Å³ª(0) ¿¡·¯°¡ ¹ß»ýÇÑ °æ¿ì(-1) ÀÌ´Ù. ÀÌÈÄ¿¡ ´Ù½Ã »ìÆ캸°ÚÁö¸¸ ÀÌ ¸®ÅÏ°ªÀ» ¹Þ¾ÒÀ»¶§¿¡
?TEpollSocket˼
?OnError¸¦ È£ÃâÇÑ ÈÄ¿¡ ¼ÒÄÏ¿¬°áÇØÁ¦(close() È£Ãâ), epoll °ü½Éfd »èÁ¦,
?TClient °´Ã¼ »èÁ¦¸¦ ¼öÇàÇϵµ·Ï ÀÛ¼ºÇÒ °ÍÀÌ´Ù. Áï,
?OnRead¿¡¼ »ç¿ëÀÚ´Â Àß Àоú´ÂÁö ¸ø Àоú´ÂÁö ÆǺ°Çؼ Àû´çÇÑ °ªÀ» ¸®ÅÏÇØÁÖµµ·Ï ÀÛ¼ºÇÏ¸é µÈ´Ù.
?OnWrite ¿¡¼µµ ¸¶Âù°¡Áö. ¿¡·¯Ã³¸®´Â
?TEpollSocketÀÌ ¾Ë¾Æ¼ ÇÑ´Ù. »ç¿ëÀÚ´Â ¾î¶² ÀϵéÀÌ ÀϾ¾ú´ÂÁö¿¡ °ü½ÉÀ» °¡Áö±â¸¸ ÇÏ¸é µÈ´Ù.
¿©±â±îÁö »ç¿ëÀÚ ±¸ÇöºÎºÐÀÌ´Ù. ´Ù½Ã Á¤¸®Çϸé, »ç¿ëÀÚ°¡ ±¸ÇöÇÒ ºÎºÐÀº main°ú
?TClientÀÇ ¼¼ °¡»óÇÔ¼öÀÇ ±¸ÇöÀÌ´Ù. ÀÌ ¼¼ ÇÔ¼öÀÇ ¸®ÅÏ°ªÀÌ
?TEpollSocket ÀÇ ¿¡·¯Ã³¸®¸¦ ¿òÁ÷À̹ǷΠÀû´çÇÑ °ªÀ» ¸®ÅÏÇÏ´Â °Íµµ Áß¿ä.
4 ±¸Çö #2 : ?TEpollSocketÀÇ ±¸Çö #
class TEpollSocket
{
protected :
int fd_listen;
// À̺κÐÀº ÅÆÇø´À¸·Î map<int, T *> mapClient; ·Î º¯°æÇÒ °ÍÀÌ´Ù.
map<int, TEpollClient *> mapClient;
TEpoll *epoll;
int SetNonBlocking(int fd);
virtual int OnEvent(TEpollEvent &event);
virtual int OnAccept(const int fd, const char *ipaddr);
virtual int OnDisconnect(const int fd);
public :
TEpollSocket(const int size);
~TEpollSocket();
int Listen(const unsigned nport);
// ¼¹ö¶ó¼ connect´Â ¾ÆÁ÷ ±¸ÇöÇÏÁö ¾ÊÀ½ --;
// int Connect(...)
int Do(int nwait);
};
3°³ÀÇ Private ÇÔ¼ö On...µéÀº Do () ¿¡¼ ÆÄ»ýµÇ¾î È£ÃâµÇ´Â ³»ºÎÇÔ¼öµéÀÌ´Ù. Áï, Ŭ·¡½º ¿ÜºÎ¿¡¼ÀÇ Do È£Ãâ·Î À̺¥Æ®µéÀ» °¨ÁöÇÏ°í ¹«½¼ÀÏÀÌ »ý°å´Ù¸é °¢ À̺¥Æ® Çڵ鸵ÇÔ¼ö¸¦ È£ÃâÇϵµ·Ï ÇÏ¿´´Ù. ÀÌ ÇÔ¼öµéÀº ÀçÁ¤ÀÇ °¡´ÉÇÏ´Ù (´Ù¸¸, ºÎ¸ð ÇÔ¼ö¸¦ È£ÃâÇØÁִ ó¸®´Â ÇØÁà¾ß ÇÑ´Ù!)
constructor & destructor
TEpollSocket::TEpollSocket(const int size)
{
epoll = new TEpoll(size);
fd_listen = 0;
}
TEpollSocket::~TEpollSocket()
{
TEpollClient *tmpClient;
while(! mapClient.empty() ){
tmpClient = mapClient.begin()->second;
delete tmpClient;
mapClient.erase(mapClient.begin());
}
if(fd_listen) close(fd_listen);
delete epoll;
}
map<int,
?TEpollClient *> À̱⶧¹®¿¡, ±ÍÂú°Ô ¸ðµÎ delete ÇØÁá´Ù. ¸¸¾à Æ÷ÀÎÅÍŸÀÔÀÌ ¾Æ´Ñ °´Ã¼ ±×´ë·Î¸¦ º¸°üÇÑ´Ù¸é mapClient.clear(); ÇÑÁÙ·Î ³¡³¯ÅÙµ¥... ÇÏÁö¸¸ °´Ã¼º¹»ç°°Àº ´õ °ñÄ¡¾ÆÇ ¹®Á¦µéÀÌ ÀÖ¾î¼ Æ÷ÀÎÅÍÀÇ ¸ÊÀ¸·Î ±¸ÇöÇß´Ù. Á÷Á¢ Çѹø map<int,
?TEpollClient> Çü½ÄÀ¸·Î ±¸ÇöÇØ º¸½Ç.
Listen() ±¸Çö
// ´Ù¸¥ Çì´õÆÄÀÏ¿¡ Á¤ÀÇÇÔ
#define EP_ERROR -3
#define EP_ERROR_SOCKET -4
#define EP_ERROR_BIND -5
#define EP_ERROR_LISTEN -6
#define EP_ERROR_LISTEN_ALREADY -7
int TEpollSocket::Listen(const unsigned nport)
{
if(fd_listen) return EP_ERROR_LISTEN_ALREADY;
struct sockaddr_in server_addr, client_addr;
int one=1, addrlen = sizeof(struct sockaddr_in);
if ((fd_listen = socket(PF_INET, SOCK_STREAM, 0)) < 0) return EP_ERROR_SOCKET;
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(nport);
setsockopt(fd_listen, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
if((bind(fd_listen, (struct sockaddr *)&server_addr, sizeof(server_addr))) < 0 ){
close(fd_listen);
return EP_ERROR_BIND;
}
if(listen(fd_listen, MAX_PENDING) < 0){
close(fd_listen);
return EP_ERROR_LISTEN;
}
// Epoll¿¡ Ãß°¡
epoll->Add(fd_listen);
return EP_ERROR_NONE;
}
¾Õ¼ Á¦ÀÛÇÑ Listen°ú´Â °ÅÀÇ ºñ½ÁÇѵ¥, ÇϳªÀÇ
?TEpollSocket¿¡¼ Çѹø¸¸ listen Çϵµ·Ï Çß´Ù. ¹°·Ð listen fd list¸¦ ±¸¼ºÇÏ°í, Á¢¼Ó½Ãµµ°¡ ÀÖÀ»¶§ ÀÌ ¸®½ºÆ® °Ë»ç¸¦ Çϵµ·Ï ¼öÁ¤Çϸé ÇϳªÀÇ
?TEpollSocket °´Ã¼¿¡¼ ¿©·¯°³ÀÇ Æ÷Æ®¸¦ listenÇÒ ¼ö ÀÖÀ¸³ª... °³¹ßÀÚ ÀÔÀå¿¡¼´Â 1:1·Î ±¸¼ºÇÏ´Â°Ô ´õ ÆíÇÒ µí Çß´Ù.
Do()ÀÇ ±¸Çö
int TEpollSocket::Do(int nwait)
{
int i, n, result;
int fd_client;
TEpollEvent events[MAX_EVENTS];
struct sockaddr_in addr;
char cliaddr[MAX_ADDR];
int addrlen = sizeof(addr);
if(! epoll->is_epoll_init){
perror("epoll init error\n");
exit(-1);
}
n = epoll->Do(events, MAX_EVENTS, nwait);
for(i=0; i<n; ++i){
// check new connection
if(fd_listen == events[i].data.fd){
// checking epoll_listensocket_list
fd_client = accept(events[i].data.fd, (struct sockaddr *) &addr, (socklen_t *) &addrlen);
if(fd_client < 0){
continue;
}
strcpy(cliaddr,inet_ntoa(addr.sin_addr));
OnAccept(fd_client, cliaddr);
} else {
if(OnEvent(events[i]) < 1){
OnDisconnect(events[i].data.fd);
close(events[i].data.fd);
epoll->Delete(events[i].data.fd);
break;
}
}
}
return n;
}
DoÀÇ ±¸ÇöÀÇ ÇÙ½ÉÀº, epoll_waitÀÇ °á°ú󸮿¡ ÀÖ´Ù. nwaitµ¿¾È ±â´Ù¸®¸é¼ °¨½ÃÇÏ´Ù°¡ À̺¥Æ®°¡ ¹ß»ýÇÑ °æ¿ì, (1) fd_listen¿¡¼ ÀÏ¾î³ ÀÏÀ̸é
?OnAccept¸¦ È£Ãâ, (2) ´Ù¸¥ ¿¬°á¿¡¼ ÀÏ¾î³ ÀÏÀ̸é
?OnEvent¸¦ È£Ãâ, (3)
?OnEvent¿¡¼ ¿¡·¯°¡ ¹ß»ýÇÑ °æ¿ì
?OnDisconnect È£Ãâ ÀÌÁ¤µµÀÇ È帧ÀÌ´Ù. ¾Õ¼ ¼³¸íÇßÁö¸¸ ¿¡·¯°¡ ¹ß»ýÇßÀ»¶§¿¡´Â ´ÙÀ½ ÀýÂ÷¸¦ µû¸¥´Ù.
- ?OnRead, ?OnWrite¿¡¼ ¿¡·¯¹ß»ý½Ã ¿¡·¯ÄÚµå ¸®ÅÏ (EP_ERROR ... ½Ã¸®Áî)
- ?OnEvent¿¡¼ ÀÌ Äڵ带 ¹Þ¾Æ¼ ?OnError·Î Àü´ÞÇϵµ·Ï µÇ¾î ÀÖÀ¸¹Ç·Î, ?OnError±¸Çö½Ã¿¡ ÀûÀýÈ÷ ó¸® (¾Æ¹«°Íµµ ¾ÈÇØÁ൵ µÈ´Ù¸¸...)
- ÃÖÁ¾ÀûÀ¸·Î ?OnEvent´Â ?OnErrorÀÇ ¿¡·¯Äڵ带 Do ÇÔ¼ö¿¡ µÇµ¹¸²
- Do ÇÔ¼ö´Â ?OnDisconnect¸¦ È£ÃâÇѹø ÇÑ ÈÄ¿¡ ¼ÒÄÏÁ¾·áó¸®.
?OnAccept()ÀÇ ±¸Çö
int TEpollSocket::OnAccept(const int fd, const char *ipaddr)
{
cout << "OnAccept\n";
SetNonBlocking(fd);
epoll->Add(fd);
mapClient[fd] = new TEpollClient (fd, ipaddr);
return mapClient.size();
}
epoll¿¡ °ü½Éfd¸¦ µî·ÏÇÏ°í, »õ
?TEpollClient °´Ã¼¸¦ ¸¸µé¾î map<> ÄÁÅ×À̳ʿ¡ µî·ÏÇϵµ·Ï ÇÏ¿´´Ù.
?OnEvent()ÀÇ ±¸Çö
int TEpollSocket::OnEvent(TEpollEvent &event)
{
TEpollClient *tmpClient = mapClient[event.data.fd];
if(! tmpClient) return 1; // ¿¡·¯´Â ¾Æ´Ï´Ù
int nread, nwrite;
char buf[1024];
if( event.events & EPOLLIN ){
cout << "onRead\n";
nread = tmpClient->OnRead();
if( nread < 1) return tmpClient->OnError(nread);
}
if( event.events & EPOLLOUT){
cout << "onWrite\n";
nread = tmpClient->OnWrite();
if( nread < 1) return tmpClient->OnError(nread);
}
if( event.events & EPOLLERR){
cout << "onError\n";
return tmpClient->OnError(EP_ERROR_GEN);
}
return 1;
}
?OnEventÀÇ ±¸ÇöÀº, ¾î¶² À̺¥Æ®°¡ ¹ß»ýÇß´ÂÁö¿¡ µû¶ó Ŭ¶óÀ̾ðÆ®ÀÇ
?OnRead,
?OnWrite,
?OnError¸¦ È£ÃâÇϵµ·Ï Çß´Ù. epoll_event.events°¡ ºñÆ®¼ÂÀÌ¾î¼ µ¿½Ã¿¡ ¿©·¯°³ÀÇ À̺¥Æ®°¡ ¹ß»ýÇÒ ¼ö ÀÖÀ¸¹Ç·Î ¿¡·¯¸¸ ¾ø´Ù¸é ¸ðµç À̺¥Æ® 󸮸¦ ´Ù Çϵµ·Ï Çß°í, ¿¡·¯°¡ ¹ß»ýÇÏ¸é ¹Ù·Î
?OnError·Î 󸮸¦ ³Ñ±âµµ·Ï Çß´Ù.
?OnDisconnect()ÀÇ ±¸Çö
int TEpollSocket::OnDisconnect(const int fd)
{
cout << "OnDisconnect\n";
TEPollClient *tmpClient = mapClient[fd];
if(! tmpClient) return -1;
mapClient.erase(fd);
delete tmpClient;
return mapClient.size();
}
Á¾·á󸮴Â, ÇØ´ç Client¸¦ ã¾Æ¼ delete ÇØÁÖ°í map<>ÄÁÅ×À̳ʿ¡¼µµ Æ÷ÀÎÅ͸¦ »èÁ¦. ¿©±â±îÁö Çؼ
?TEpollSocketÀÇ ±¸ÇöÀÌ ¿Ï·á!
?TEpollClient¸¦ ÇÁ·Î±×·¡¸Ó°¡ ¸Å¹ø°íÃļ ¾²µµ·Ï Çϱ⿡´Â ³Ê¹« ¹ø°Å·Ó±â ¶§¹®¿¡, Ãß»óÈ°èÃþÀ¸·Î ¼û°Ü³õ°í À̸¦ »ó¼Ó¹Þ¾Æ »ç¿ëÇÏ°Ô ÇÏ·Á´Â°Ô ¿ø·¡ ¸ñÀûÀ̾úÀ¸¹Ç·Î,
?TEpollClient»Ó¸¸ ¾Æ´Ï¶ó ÀÌ Àڽĵé Áß ¾î¶²°ÍÀÌ¶óµµ Ä¿½ºÅ͸¶ÀÌÁîÇÏ¿© »ç¿ëÇÏ·Á¸é template·Î ±¸ÇöÇÏ´Â ¼ö¹Û¿¡ ¾øÀ» µíÇÏ´Ù. (¾Õ¿¡¼µµ ½èÁö¸¸ ´õ ³ªÀº ¹æ¹ýÀÌ ÀÖ´Ù¸é ¾Ë·ÁÁÖ¼¼¿ä)
¿Ï¼ºµÈ ?TEpollSocket
template <class T>
class TEpollSocket
{
private :
int fd_listen;
map<int, T*> mapClient;
TEpoll *epoll;
int SetNonBlocking(int fd);
virtual int OnEvent(TEpollEvent &event);
virtual int OnAccept(const int fd, const char *ipaddr);
virtual int OnDisconnect(const int fd);
public :
TEpollSocket(const int size);
~TEpollSocket();
int Listen(const unsigned nport);
int Do(int nwait);
};
4.2 Sources / ?EpSocket ver 1.0 #
5 ÀÌÈÄÀÇ ±¸Çö°èȹ #
- Read, WriteÀÇ ¹öÆÛ¸µ ±¸Çö
- Ŭ¶óÀ̾ðÆ® <-> ¼¹ö°£ ¸Þ½Ã¡ ±¸Çö
- ÃÖÁ¾¿Ï¼ºµÈ ¼ÒÄÏŬ·¡½º¸¦ ÀÌ¿ëÇÏ¿© äÆü¹ö ±¸Çö