IOCP - Input/Output Completion Port
ÃÑ ÆäÀÌÁö ¼ö : 3224

Àüü ÇÔ¼ö/¿ë¾î»çÀü
Facebook Joinc ±×·ì   Joinc QA »çÀÌÆ®



joinc´Â Firefox¿Í chrome¿¡¼­ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼­´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù.

IOCP¿¡ ´ëÇÏ¿©

IOCP´Â Input/Ouptput Completion PortÀÇ ¾àÀÚ´Ù. ÀԷ°ú Ãâ·ÂÀÇ ¿Ï·á¸¦ ´ã´çÇÒ Æ÷Æ®¸¦ ÁöÁ¤Çؼ­ ó¸®Çϰڴٴ Àǹ̴Ù. ÀԷ°ú Ãâ·ÂÀÇ ¿Ï·á½ÃÁ¡¿¡¼­ÀÇ ÅëÁö´Â overlapped(Áßø ÀÔÃâ·Â)¿¡¼­ 󸮰¡ µÇ¹Ç·Î, ÀÌ ±â¼úÀº À©µµÀÇ Áßø ÀÔÃâ·Â ±â¼úÀ» È®Àå½ÃŲ °ÍÀ¸·Î º¼ ¼ö ÀÖ´Ù.

Æ÷Æ®´Â ÀÛ¾÷ ȤÀº ¼­ºñ½º¸¦ Àü´ãÇϱâ À§Çؼ­ ¸¸µé¾îÁö´Â °´Ã¼´Ù. ¼ÒÄÏÀÇ Æ÷Æ®°¡ ƯÁ¤ ¼­ºñ½º·Î µ¥ÀÌÅÍ ÀÔÃâ·ÂÀ» Àü´ÞÇϱâ À§ÇÑ °´Ã¼ÀÓÀ» »ó±âÇϸé ÀÌÇØ°¡ ½¬¿ï °ÍÀÌ´Ù. ÀÌ·¯ÇÑ Æ÷Æ®ÀÇ Æ¯Â¡À» ÀÌÇØÇϸé, ÀÔÃâ·Â ¿Ï·á ½ÃÁ¡¿¡¼­ ÀÌ¿¡ ´ëÇÑ ÅëÁö¸¦ Àü´ãÇÒ Æ÷Æ®¸¦ ¸¸µé¾î¼­ µ¥ÀÌÅ͸¦ ó¸®ÇÏ´Â ¹æ½Äµµ ÃæºÐÈ÷ »ý°¢ÇØ º¼ ¼ö ÀÖÀ» °ÍÀÌ´Ù.


ÀÔÃâ·Â ÀåÄ¡ (¿©±â¿¡¼­´Â ¼ÒÄÏÀ¸·Î ÇÑÁ¤ÇÑ´Ù.)·Î ºÎÅÍ ÀÔÃâ·ÂÀÌ ¿Ï·áµÇ¸é, ÀÌ ¿Ï·áº¸°í´Â ÀÔÃâ·Â ¿Ï·á ´ë±â¿­¿¡ ½×ÀδÙ. ±×·¯¸é ½º·¹µå¸¦ ±ú¿ì°Ô µÇ°í, ½º·¹µå´Â ´ë±â¿­¿¡ ÀÖ´Â ¿Ï·áº¸°í¸¦ Àо µ¥ÀÌÅ͸¦ ó¸®ÇÏ´Â ½ÄÀÌ´Ù.

ÀÌ ¹æ½ÄÀÇ ÀåÁ¡Àº Ŭ¶óÀÌ¾ðÆ®°¡ ¿¬°á ÇÒ ¶§ ¸¶´Ù ½º·¹µå¸¦ ¸¸µå´Â ¸ÖƼ ½º·¹µå ¹æ½Ä°ú ´Þ¸®, ¹Ì¸® ½º·¹µå¸¦ ¸¸µé¾î¼­ ÀÔÃâ·Â ¿Ï·á º¸°í¸¦ ±â´Ù¸®µµ·Ï ÇÒ ¼ö ÀÖ´Ù´Â Á¡ÀÌ´Ù. ÀÌ·¸°Ô Àû´çÇÑ °³¼öÀÇ ¿öÄ¿ ½º·¹µå¸¦ ¸¸µé¾î µÎ¸é, ¿î¿µÃ¼Á¦°¡ ½¬°í ÀÖ´Â ¿öÄ¿ ½º·¹µå¸¦ ±ú¿ï ¼ö ÀÖ´Ù. ÀÌ ¹æ½ÄÀº ½º·¹µå ȤÀº ÇÁ·Î¼¼½º Ç®°ú ºñ½ÁÇØ º¸À̱⵵ ÇÏÁö¸¸ Â÷À̰¡ ÀÖ´Ù. ÀϹÝÀûÀ¸·Î ½º·¹µå Ç® ¹æ½Ä¿¡¼­´Â ½¬°í ÀÖ´Â ½º·¹µå¿¡ ÀÛ¾÷À» ÇÒ´çÇϱⰡ ¼ö¿ùÇÏÁö ¾Ê´Ù. ÀÌ·¸°Ô ÇÏ·Á¸é ¸î °¡Áö ±î´Ù·Î¿î ±â¹ýÀ» »ç¿ëÇØ¾ß Çϴµ¥, IOCP´Â °³¹ßÀÚ°¡ ½Å°æ ¾µ ÇÊ¿ä ¾øÀÌ ¿î¿µÃ¼Á¦°¡ ¾Ë¾Æ¼­ ½º·¹µå¸¦ ¼±ÅÃÇØ¼­ ±ú¿î´Ù.

Áßø ¼ÒÄÏ Æ¯Â¡À» »ç¿ëÇϹǷÎ, °¡´ÉÇϸé WSA °è¿­ÀÇ À©¼Ó È®Àå ÇÔ¼ö·Î µ¥ÀÌÅ͸¦ ó¸®ÇÏ´Â °ÍÀ» ±ÇÀå ÇÑ´Ù.

IOCP ÇÁ·Î±×·¡¹Ö

IOCP ÇÁ·Î±×·¥Àº ´ÙÀ½°ú °°Àº °úÁ¤À» °ÅÄ£´Ù. ÀÔ·ÂÀ» ±âÁØÀ¸·Î ¼³¸íÇÑ´Ù.
  1. ¿öÄ¿ ½º·¹µå »ý¼º : Àû´çÇÑ °³¼öÀÇ ¿öÄ¿ ½º·¹µå¸¦ ¸¸µç´Ù.
    1. ¿öÄ¿ ½º·¹µå´Â ¿Ï·á º¸°í ÅëÁö¸¦ ±â´Ù¸°´Ù.
  2. ¼ÒÄÏ »ý¼º
  3. accept ÇÔ¼ö È£Ãâ
  4. ¿¬°á µÇ¸é, ¼ÒÄÏÀ» CP (Completion Port)¿¡ ÇÒ´çÇÑ´Ù.
  5. WSARecvÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. ¼ÒÄÏÀº ºñµ¿±â, Áßø ¼ÒÄÏÀÌ´Ù.

¿öÄ¿ ½º·¹µå

¿öÄ¿ ½º·¹µå´Â GetQueuedCompletionStatus·Î ¿Ï·á Å뺸¸¦ ±â´Ù¸°´Ù. ÀÌ ÇÔ¼ö´Â OVERLAPPED ±¸Á¶Ã¼¸¦ µÇµ¹·Á Áִµ¥, ÀÌ ±¸Á¶Ã¼¿¡¼­ Á¤º¸¸¦ Åä´ë·Î µ¥ÀÌÅ͸¦ ó¸®ÇÏ¸é µÈ´Ù.

¼ÒÄÏÀ» CP¿¡ ÇÒ´çÇϱâ

ÆÄÀÏ °ü¸® ÇÔ¼öÀÎ CreateIoCompletionPortÇÔ¼ö·Î ¼ÒÄÏÀ» CP¿¡ ÇÒ´çÇÒ ¼ö ÀÖ´Ù. ÀÌÁ¦ ÇØ´ç ¼ÒÄÏ¿¡ ÀÔÃâ·Â ¿Ï·á°¡ ÀÌ·ç¾îÁö¸é ÀÔÃâ·Â ¿Ï·á ´ë±â¿­¿¡ ¿Ï·áº¸°í°¡ ½×À̰í, ¿öÄ¿ ½º·¹µåµé Áß Çϳª°¡ ±ú¾î³ª¼­ ÀÛ¾÷À» ó¸®ÇÑ´Ù.

CreateCompletionPort ÇÔ¼ö´Â HANDLEÀ» µî·Ï½ÃŰ´Â ÇÔ¼öÀ̹ǷÎ, ¼ÒÄÏÀÇ °æ¿ì HANDLE·Î Çü º¯È¯ ÇØ¼­ »ç¿ëÇØ¾ß ÇÑ´Ù.

ºñµ¿±â ÀÔÃâ·Â ¼öÇà

WSA °è¿­ ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ (Áßø)ºñµ¿±â ÀÔÃâ·ÂÀ» ¼öÇàÇÑ´Ù. ÀÌ ³»¿ëÀº Áßø ÀÔÃâ·Â ¸ðµ¨¹®¼­¸¦ Âü°íÇϱ⠹ٶõ´Ù.


¿¹Á¦ ÇÁ·Î±×·¥

Ŭ¶óÀÌ¾ðÆ® ¿¬°á ´ç ½º·¹µå¸¦ ¸¸µå´Â ¹æ½ÄÀÌ ¾Æ´Ñ, ÀԷ´ç ó¸® ½º·¹µå¸¦ ½ºÄÉÁ층 ÇÏ´Â ¹æ½ÄÀ¸·Î ¸Å¿ì È¿À²ÀûÀ¸·Î ÀÛµ¿ÇÑ´Ù. ÀϹÝÀûÀ¸·Î ¸ðµç ¿î¿µÃ¼Á¦¸¦ ÅëÆ²¾î °¡Àå È¿À²ÀûÀÎ ÀÔÃâ·Â ¸ðµ¨ Áß Çϳª·Î ÀÎÁ¤Çϰí ÀÖ´Ù.

±âº»ÀûÀÎ È帧Àº ¸Å¿ì ´Ü¼øÇÏ´Ù. ½ÇÁ¦, ÇÁ·Î±×·¥ ±¸¼º°ú È帧¸¸À» ³õ°í º¸¸é WSAEventSelect, WSAAsyncSelect ¸ðµ¨º¸´Ù ´õ °£´ÜÇÏ´Ù. ¶§¶§·Î ÀÛµ¿¹æ½ÄÀ» ÀÌÇØÇϱâ Èûµé´Ù´Â Æò°¡°¡ Àֱ⵵ ÇÏÁö¸¸ Áßø ¼ÒÄÏÀÇ Æ¯Â¡À» ÀÌÇØÇÑ´Ù¸é Å©°Ô ¾î·Æ´Ù°í »ý°¢µÇÁö ¾Ê´Â´Ù.

¿öÄ¿ ½º·¹µå¸¦ ¸ÕÀú ¸¸µé¾î ³õ°í, ÀÛ¾÷À» ÇÒ´çÇÏ´Â °ÍÀº ½º·¹µå Ç® µîÀÇ ±â¼ú·Î ÀÌ¹Ì ÀÀ¿ë ±¸ÇöµÇ¾î Àֱ⵵ ÇÏ´Ù. ½º·¹µå Ç®¿¡ ´ëÇÑ ³»¿ëÀº ¾²·¹µå Ç®¹®¼­¸¦ Âü°íÇϱ⠹ٶõ´Ù. Âü°í ¹®¼­´Â ÀÔ·Â´ç ¾²·¹µå ÇÒ´çÀÌ ¾Æ´Ñ, ¿¬°á´ç ¾²·¹µå ÇÒ´çÀ¸·Î IOCPÀÇ ±×°Í°ú´Â ¾à°£ÀÇ Â÷À̰¡ ÀÖÁö¸¸ ¿ø¸®¸¦ ÀÌÇØÇÏ´Â µ¥¿¡´Â ¹®Á¦ ¾øÀ¸¸®¶ó »ý°¢µÈ´Ù. IOCP ó·³ ÀÔ·Â´ç ¾²·¹µå ÇÒ´çÀ¸·Î ÇÏ·Á¸é ¾à°£ÀÇ ¼öÁ¤ÀÌ ÀÖ¾î¾ß ÇÑ´Ù.

#include <stdio.h> 
#include <winsock2.h> 
 
#define MAXLINE 1024 
 
// ¼ÒÄÏ Á¤º¸ ±¸Á¶Ã¼ OVERLAPPED·Î ij½ºÆÃ µÇ¾î¼­ ³Ñ¾î°£´Ù. 
struct SocketInfo 
{ 
    OVERLAPPED overlapped; 
    SOCKET fd; 
    char buf[MAXLINE]; 
    int readn; 
    int writen; 
    WSABUF wsabuf; 
 
}; 
 
HANDLE g_hIocp; 
 
// ¿öÄ¿ ½º·¹µå ÇÔ¼ö 
unsigned int WINAPI Thread_func(LPVOID parm) 
{ 
    int readn; 
    int coKey; 
    int flags = 0; 
    OVERLAPPED *overlapped; 
    struct SocketInfo *sInfo; 
    while(1) 
    {    
        // IOCP·ÎºÎÅÍ ¿Ï·áµÈ ÀÔÃâ·Â º¸°í°¡ ÀÖ´ÂÁö È®ÀÎÇÑ´Ù.  
        GetQueuedCompletionStatus(g_hIocp, &readn, &coKey, (LPOVERLAPPED *)&overlapped, INFINITE); 
        sInfo = (struct SocketInfo *)coKey; 
        if(readn == 0) 
        { 
            printf("close socket %d\n", sInfo->fd); 
            closesocket(sInfo->fd); 
            free(sInfo); 
            continue; 
        } 
        memset(&(sInfo->overlapped), 0x00, sizeof(OVERLAPPED)); 
        send(sInfo->fd, sInfo->wsabuf.buf, sInfo->wsabuf.len, 0); 
        WSARecv(sInfo->fd, &sInfo->wsabuf, 1, &readn, &flags, &sInfo->overlapped, NULL); 
    } 
} 
 
 
int main(int argc, char **argv) 
{ 
    WSADATA wsaData; 
    struct sockaddr_in addr; 
    struct SocketInfo *sInfo; 
    SOCKET listen_fd, client_fd; 
    HANDLE hThread[10]; 
    DWORD  ThreadArray[10]; 
    int flags; 
    int readn, addrlen, i; 
 
    if (argc != 2) 
    { 
        printf("Usage : %s [port num]\n", argv[0]); 
        return 1; 
    } 
 
    if(WSAStartup(MAKEWORD(1,1), &wsaData) != 0) 
    { 
        return 1; 
    } 
     
    if((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) 
    { 
        return 1; 
    } 
 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(atoi(argv[1])); 
    addr.sin_addr.s_addr=htonl(INADDR_ANY); 
 
    if( bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr) ) == SOCKET_ERROR) 
    { 
        return 1; 
    } 
 
    if( listen(listen_fd, 5) == SOCKET_ERROR) 
    { 
        return 1; 
    } 
 
    // IOCP¸¦ ¸¸µç´Ù.  
    g_hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); 
 
    for(i = 0; i < 10; i++) 
    { 
        hThread[i] = CreateThread(NULL, 0, Thread_func, 0, 0, &ThreadArray[i]); 
    } 
 
    while(TRUE) 
    { 
        addrlen = sizeof(addr); 
        client_fd = accept(listen_fd, (struct sockaddr *)&addr, &addrlen); 
        if(client_fd == INVALID_SOCKET) 
        { 
        } 
        sInfo = (void *)malloc(sizeof(struct SocketInfo)); 
        memset((void *)sInfo, 0x00, sizeof(struct SocketInfo)); 
        sInfo->fd = client_fd; 
        sInfo->readn = 0; 
        sInfo->writen = 0; 
        sInfo->wsabuf.buf = sInfo->buf; 
        sInfo->wsabuf.len = MAXLINE; 
        // ¼ÒÄÏÀ» IOCP¿¡ µî·ÏÇÑ´Ù.     
        if((g_hIocp = CreateIoCompletionPort((HANDLE)client_fd, g_hIocp, (unsigned long)sInfo, 0)) == NULL) 
        { 
            printf("CreateIoCompletionPort Error\n"); 
            return 1; 
        } 
        flags = 0; 
        readn = MAXLINE; 
 
        // WSARecv·Î Áßø ÀÔ·Â ¿¬»êÀ» ¼öÇàÇÑ´Ù. 
        if(WSARecv(sInfo->fd, &sInfo->wsabuf, 1, &readn, &flags, &sInfo->overlapped, NULL) == SOCKET_ERROR) 
        { 
            if(WSAGetLastError() == ERROR_IO_PENDING) 
            { 
                printf("WSARecv Success\n"); 
            } 
            else 
            { 
                printf("WRSRecv Error %d : %d\n", sInfo->fd, WSAGetLastError()); 
                return 1; 
            } 
        } 
    } 
} 
 
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù.