FrontPage|FindPage|TitleIndex|RecentChanges|RSS Epoll Socket
 
¼ÒÄÏ°ü·ÃµÈ ÀϵéÀ» Æ÷°ýÇÏ´Â ?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 Ŭ·¡½º ¼³°è °í¹Î = »ðÁú --; #

¸çÄ¥µ¿¾È °í¹ÎÀ» ÇßÀ½. °í¹ÎÀÇ ¼ø¼­¸¦ ¤¾îº¸ÀÚ.

  1. main ÇÁ·Î±×·¡¸Ó°¡ °æÇèÀÌ ÀÖ°í ÀÀ¿ë·ÂÀÌ ÀÖ´Ù¸é, »ùÇà ¼Ò½º¸¸ º¸°í ¾ó¸¶µçÁö © ¼ö ÀÖÀ»ÅÙµ¥ ±¸Å¿© ¿Ö? ... ±×·¸Áö¸¸ ¹º°¡ ÂóÂóÇÏ´Ù.
  2. Client Ŭ·¡½º±îÁö ¸¸µé¾îÁà¹ö¸®°í, SocketŬ·¡½º°¡ Ŭ¶óÀ̾ðÆ® »ý¼º, ¼Ò¸ê±îÁö ¾Ë¾Æ¼­ ´Ù Çعö¸®µµ·Ï ÇÏÀÚ. ¾ÆÁÖ ±ò²ûÇÏ°í ÆíÇÏ´Ù (ÀÎÅͳݿ¡ µ¹¾Æ´Ù´Ï´Â c++¼Ò½ºµéµµ ´ëºÎºÐ ÀÌ·± °ñ°ÝÀÌ´Ù). ÇÏÁö¸¸ Client Ŭ·¡½º°¡ º¹ÀâÇØÁú¼ö·Ï ÀÌ ±¸Á¶´Â ²ûÂïÇÒ µí ÇÏ´Ù. °Ô´Ù°¡ epoll ÇÔ¼öµéµµ ²ø°í ´ó°Ü¾ß ÇÑ´Ù. µ¶¸³¸ðµâ·Î ºÐ¸®ÇÒ ¼ö°¡ ¾ø´Ù.
  3. ¼ÒÄÏÀ̺¥Æ®¿¡ ÄݹéÇÔ¼ö¸¦ ¿¬°á½ÃÅ°ÀÚ!! ¼ÒÄϵ鿡¼­ ¹«½¼ÀÏÀÌ »ý±â¸é ³»°¡ ¸¸µç ÇÔ¼ö°¡ È£ÃâµÇµµ·Ï ±¸¼ºÇÑ´Ù. ?CSock µîÀÌ ÀÌ·±¹æ½ÄÀ» ÃëÇÏ°í ÀÖ´Ù. ÇÏÁö¸¸ ÇÔ¼öÀÇ Æ÷ÀÎÅÍ ´Ù·ç±â°¡ ¸¸¸¸Ä¡ ¾Ê´Ù. ¿©·¯ Á¾·ùÀÇ ClientµéÀÌ Á¸ÀçÇÒ °æ¿ì¿¡ ÇÁ·Î±×·¥Àº À̷縻ÇÒ ¼ö ¾øÀÌ º¹ÀâÇØÁø´Ù.
  4. ÁÁ´Ù! template¸¦ ÀÌ¿ëÇÏÀÚ. ?BasicClient Ŭ·¡½º¸¦ Á¦°øÇØÁÖ°í »ç¿ëÀÚ·Î ÇÏ¿©±Ý ÀÌ°ÍÀ» »ó¼Ó¹Þ¾Æ ¸Ú´ë·Î Ŭ·¡½º¸¦ ¸¸µéµµ·Ï ÇÏ°í, ÀÌ·± Ä¿½ºÅ͸¶ÀÌ¡µÈ Client Ŭ·¡½º¸¦ ÆĶó¹ÌÅÍ·Î ÇÏ´Â template socket class ¸¦ ¸¸µéÀÚ!!

»ý°¢ÀÌ 4¹ø±îÁö Çϴµ¿¾È ½ÇÁ¦·Î À̰͵éÀ» ±¸ÇöÇغ¸¸é¼­ ¼Ò½º¸¦ 100¹øµµ ³Ñ°Ô ¼öÁ¤ÇÏ°í °³¼±ÇÏ¿´´Ù. ÀÌ ?TEpollSocket Ŭ·¡½º¸¦ ÀÌ¿ëÇؼ­ äÆü­¹ö´Â ¹°·Ð »ó¾÷Àû ¿Â¶óÀΰÔÀÓ±îÁö ±¸ÇöÀÌ °¡´ÉÇϵµ·Ï ¸¹Àº »ý°¢À» ÇØ ³»¾ß¸¸ Çß´Ù.

¹°·Ð ´õ ³ªÀº ¼³°è°¡ °¡´ÉÇÏ´Ù¸é, ¾ðÁ¦µçÁö Á¶¾ðÀ» ... !!


2 ±¸ÇöÀÇ ¼ø¼­ #


  1. ¸ÕÀú template ¾øÀÌ ±âº»¼ÒÄÏŬ¶óÀ̾ðÆ® Ŭ·¡½º ?TEpollClient ±¸Çö
  2. ¸¶Âù°¡Áö·Î template ¾øÀÌ ±âº» ¼ÒÄÏ Å¬·¡½º ?TEpollClass ±¸Çö
  3. µ¿ÀÛ Å×½ºÆ® - ¿ª½Ã echo ¼­¹ö --;
  4. ¼ÒÄÏŬ·¡½º ?TEpollClassÀÇ Client Ŭ·¡½º¸¦ ÅÆÇø´À¸·Î ±¸Çö
  5. ¸¶Âù°¡Áö·Î, ?TEpollClient¸¦ »ó¼ÓÇÑ ³ªÀÇ Å¬·¡½º ?TClient ±¸Çö
  6. µ¿ÀÛ Å×½ºÆ® - 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 È£Ãâ ÀÌÁ¤µµÀÇ È帧ÀÌ´Ù. ¾Õ¼­ ¼³¸íÇßÁö¸¸ ¿¡·¯°¡ ¹ß»ýÇßÀ»¶§¿¡´Â ´ÙÀ½ ÀýÂ÷¸¦ µû¸¥´Ù.

  1. ?OnRead, ?OnWrite¿¡¼­ ¿¡·¯¹ß»ý½Ã ¿¡·¯ÄÚµå ¸®ÅÏ (EP_ERROR ... ½Ã¸®Áî)
  2. ?OnEvent¿¡¼­ ÀÌ Äڵ带 ¹Þ¾Æ¼­ ?OnError·Î Àü´ÞÇϵµ·Ï µÇ¾î ÀÖÀ¸¹Ç·Î, ?OnError±¸Çö½Ã¿¡ ÀûÀýÈ÷ ó¸® (¾Æ¹«°Íµµ ¾ÈÇØÁ൵ µÈ´Ù¸¸...)
  3. ÃÖÁ¾ÀûÀ¸·Î ?OnEvent´Â ?OnErrorÀÇ ¿¡·¯Äڵ带 Do ÇÔ¼ö¿¡ µÇµ¹¸²
  4. 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ÀÇ ±¸ÇöÀÌ ¿Ï·á!


4.1 template Àû¿ë #


?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 ÀÌÈÄÀÇ ±¸Çö°èȹ #

  1. Read, WriteÀÇ ¹öÆÛ¸µ ±¸Çö
  2. Ŭ¶óÀ̾ðÆ® <-> ¼­¹ö°£ ¸Þ½Ã¡ ±¸Çö
  3. ÃÖÁ¾¿Ï¼ºµÈ ¼ÒÄÏŬ·¡½º¸¦ ÀÌ¿ëÇÏ¿© äÆü­¹ö ±¸Çö

last modified 2004-06-25 17:55:14
EditText|FindPage|DeletePage|LikePages|