¼ÒÄÏŸÀӾƿô
ÃÑ ÆäÀÌÁö ¼ö : 3224

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



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


Contents

1 ¼Ò°³
2 ³×Æ®¿öÅ© ¾îÇø®ÄÉÀÌ¼Ç ¹®Á¦¹ß»ý°ú ÇØ°á
2.1 Å×½ºÆ®¿ë ¼­¹ö/Ŭ¶óÀÌ¾ðÆ® Áغñ
3 ¹ß»ýÇÒ¼ö ÀÖ´Â ¹®Á¦µé
3.1 Ŭ¶óÀÌ¾ðÆ® ºñÁ¤»ó Á¾·á
3.2 ³×Æ®¿öÅ© ´ÜÀý
3.3 ¾îÇø®ÄÉÀ̼ÇÀÇ ºñÁ¤»óÀÛµ¿
4 ¹®Á¦ ÇØ°á
4.1 ºñÁ¤»óÁ¾·á
4.2 ³×Æ®¿öÅ© ´ÜÀý
4.2.1 alarm ÇÔ¼öÀÇ ÀÌ¿ë
4.2.2 select/poll ÀÇ ÀÌ¿ë
4.3 ¿¬°á ¼ÒÄÏ Time out ó¸®

1 ¼Ò°³

¼­¹ö / Ŭ¶óÀÌ¾ðÆ® ¸ðµ¨ ±¸ÃàÀ» À§Çؼ­ ¿ì¸®´Â º¸Åë Socket API ¸¦ »ç¿ëÇÏ°Ô µÈ´Ù. ÀÌ Socket API ´Â Àü¼Û°èÃþ ·¹º§¿¡¼­ Åë½ÅÀ» °¡´ÉÇϵµ·Ï µµ¿ÍÁÖ¸ç, ¸Å¿ì ½Å·Ú¼ºÀÖ°Ô ÀÛµ¿ÇÑ´Ù. ´ëºÎºÐÀÇ read/write ÀÛ¾÷À» ÇÒ¶§ ¹®Á¦°¡ »ý±â¸é ¹®Á¦ »óȲÀ» ¸®ÅÏÇØ Áֱ⠶§¹®¿¡ ¹®Á¦»óȲ¿¡ ´ëóÇϱ⵵ ½±´Ù.

±×·¯³ª ³×Æ®¿öÅ© ´ÜÀý, Ŭ¶óÀÌ¾ðÆ® ÇÁ·Î±×·¥ÀÇ ¿ÀÀÛµ¿(Áװųª, »ì¾Æ À־ Á¦´ë·Î ÀÛµ¿À» ¸øÇÏ´Â)ÀÇ °æ¿ì À¯¿¬ÇÏ°Ô ´ëóÇÏÁö ¸øÇÏ´Â °æ¿ì°¡ »ý±ä´Ù. ÀÌ ¹®¼­´Â ÀÌ·¯ÇÑ »óȲ¿¡ ´ëóÇϱâ À§ÇÑ ¹æ¹ýÁß °¡Àå ÀϹÝÀûÀÎ Time out À» ÀÌ¿ëÇѹæ¹ý¿¡ ´ëÇØ¼­ ¾Ë¾Æº¸µµ·Ï ÇϰڴÙ.

ÀÌ ¹®¼­ÀÇ ³»¿ëÀ» Á¦´ë·Î ÀÌÇØÇϱâ À§Çؼ­´Â TCP, IP¿¡ ´ëÇÑ ³»¿ëÀ» ÀÌÇØÇϰí ÀÖ¾î¾ß ÇÑ´Ù. À̿ܿ¡µµ ½Ã±×³Î ó¸®¿Í ÀÔÃâ·Â´ÙÁßÈ­¿Í °ü·ÃµÈ ³»¿ëÀ» ¾Ë°í ÀÖÀ¸¸é µµ¿òÀÌ µÉ°ÍÀÌ´Ù.

2 ³×Æ®¿öÅ© ¾îÇø®ÄÉÀÌ¼Ç ¹®Á¦¹ß»ý°ú ÇØ°á

2.1 Å×½ºÆ®¿ë ¼­¹ö/Ŭ¶óÀÌ¾ðÆ® Áغñ

Å×½ºÆ®¸¦ À§Çؼ­ °£´ÜÇÑ echo ¼­¹ö/Ŭ¶óÀÌ¾ðÆ®¸¦ ÁغñÇϵµ·Ï ÇϰڴÙ. ÄÚµå´Â °£´ÜÇÔÀ¸·Î ¼³¸íÀ» ÇÏÁø ¾Ê°Ú´Ù.

#include <sys/socket.h> 
#include <sys/stat.h> 
#include <arpa/inet.h> 
#include <stdio.h> 
#include <string.h> 
 
int main(int argc, char **argv) 
{ 
    int server_sockfd, client_sockfd; 
    int client_len, n; 
    char buf[80]; 
    struct sockaddr_in clientaddr, serveraddr; 
 
    client_len = sizeof(clientaddr); 
 
    if ((server_sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) 
    { 
        perror("socket error : "); 
        exit(0); 
    } 
    bzero(&serveraddr, sizeof(serveraddr)); 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    serveraddr.sin_port = htons(atoi(argv[1])); 
 
    bind (server_sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)); 
    listen(server_sockfd, 5); 
 
    while(1) 
    { 
        memset(buf, 0x00, 80); 
        client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr, 
                            &client_len); 
 
        if ((n = read(client_sockfd, buf, 80)) <= 0) 
        { 
            close(client_sockfd); 
            continue; 
        } 
        if (write(client_sockfd, buf, 80) <=0) 
        { 
            perror("write error : "); 
            close(client_sockfd); 
        } 
        close(client_sockfd); 
    } 
} 
 

echo_client.c
#include <sys/stat.h> 
#include <arpa/inet.h> 
#include <stdio.h> 
#include <string.h> 
 
int main(int argc, char **argv) 
{ 
    struct sockaddr_in serveraddr; 
    int server_sockfd; 
    int client_len; 
    char buf[80]; 
    char rbuf[80]; 
 
 
    if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
    { 
        perror("error :"); 
        exit(0); 
    } 
 
    server_sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_addr.s_addr = inet_addr("218.234.19.87"); 
    serveraddr.sin_port = htons(atoi(argv[1])); 
 
    client_len = sizeof(serveraddr); 
 
    if (connect(server_sockfd, (struct sockaddr *)&serveraddr, client_len) < 0) 
    { 
        perror("connect error :"); 
        exit(0); 
    } 
 
    memset(buf, 0x00, 80); 
    read(0, buf, 80); 
    if (write(server_sockfd, buf, 80) <= 0) 
    { 
        perror("write error : "); 
        exit(0); 
    } 
    memset(buf, 0x00, 80); 
    if (read(server_sockfd, buf, 80) <= 0) 
    { 
        perror("read error : "); 
        exit(0); 
    } 
    close(server_sockfd); 
    printf("read : %s", buf); 
} 
 

3 ¹ß»ýÇÒ¼ö ÀÖ´Â ¹®Á¦µé

3.1 Ŭ¶óÀÌ¾ðÆ® ºñÁ¤»ó Á¾·á

¿ì¸®´Â TCP ÀÚ¼¼È÷ º¸±â ¿¡¼­ Á¤»óÁ¾·á »óÅ¿¡ ´ëÇØ¼­ ¾Ë¾Æº¸¾Ò´Ù. TCP ÀÇ Á¤»ó¿¬°á ¹× Á¤»óÁ¾·á ´Â ÃÖÃÊÀÇ ¼¼¼Ç ¸ÎÀ½À» À§ÇÑ 3¹ø¾Ç¼ö±â¹ý¿¡ ÀÇÇÑ ÆÐŶ±³È¯ÀÌ ÀÌ·ç¾î Áö°Ô µÈ´Ù. Á¤»ó Á¾·áÀÇ °æ¿ì¿¡´Â Ŭ¶óÀÌ¾ðÆ®¿¡¼­ close()¸¦ È£ÃâÇϸé, FIN-ACK ÆÐŶ±³È¯ÀÌ ÀϾ°í, ¼­¹öÃø¿¡¼­´Â FIN-ACK ÈÄ close()¸¦ È£ÃâÇØ¼­ ´Ù½ÃÇѹø FIN-ACK ÆÐŶ±³È¯ÀÌ ÀϾÀ¸·Î µµÇÕ 4¹øÀÇ ÆÐŶ ±³È¯ÀÌ ÀϾ°Ô µÈ´Ù. ´ÙÀ½Àº echo ¼­¹ö/Ŭ¶óÀ̾ð ÇÁ·Î±×·¥À» ÀÌ¿ëÇØ¼­ Å×½ºÆ®ÇÑ °á°úÀÌ´Ù. ¼­¹öÃø IP ´Â 218.234.19.87 Ŭ¶óÀ̾ðÆ®Ãø IP ´Â 210.205.210.230 ÀÌ´Ù


»¡°£¿øÀ¸·Î Ç¥½ÃÇØµÐºÎºÐÀÌ ¹Ù·Î CODE BITS ¸¦ ³ªÅ¸³½´Ù. À§ÀÇ °á°ú´Â Ŭ¶óÀÌ¾ðÆ®¿¡¼­ closeÇÔ¼ö¸¦ È£ÃâÇÑÈÄ ºÎÅÍÀÇ ÆÐŶÀ» ĸÃçÇÑ ³»¿ëÀÌ´Ù. óÀ½ 2°³ÀÇ ÆÐŶÀº Ŭ¶óÀ̾ðÆ®ÀÇ close ÇÔ¼ö È£Ãâ¿¡ ÀÇÇØ¼­ ¹ß»ýÇÑ FIN-ACK ÆÐŶÀ̸ç, ¸¶Áö¸· 2°³´Â ¼­¹öÃø close ÇÔ¼ö È£Ãâ¿¡ ÀÇÇØ ¹ß»ýÇÑ FIN-ACK ÆÐŶÀÌ´Ù.

Ŭ¶óÀÌ¾ðÆ® ÇÁ·Î±×·¥ÀÌ ¼­¹ö¿¡ ¿¬°áÇØ¼­ 3¹ø ¾Ç¼ö ±â¹ý¿¡ ÀÇÇØ¼­ ¼¼¼ÇÀÌ ¸¸µé¾î Á®¼­, ÇØ´ç ¼¼¼ÇÅë·Î¸¦ ÀÌ¿ëÇØ¼­ µ¥ÀÌŸ¸¦ ÁÖ°í ¹Þ°í ÀÖ´ÂÁßÀ̶ó°í Ä¡ÀÚ, ±×·±µ¥ ¾î¶² ÀÌÀ¯·Î - À߸øµÈ ÄÚµùÀ̳ª, ½Ã½ºÅÛ È¯°æ»óÀÇ ¹®Á¦µî - ºñÁ¤»óÁ¾·á¸¦ ÇØ¹ö·È´Ù°í Çϸé, ´ç¿¬È÷ Ŭ¶óÀÌ¾ðÆ® Ãø¿¡¼­ÀÇ ¼¼¼ÇÁ¾·á°úÁ¤ÀÌ ÀϾ¼ö ¾ø°ÔµÈ´Ù. ÀÌ·²°æ¿ì ¼­¹öÃø¿¡¼­ °­Á¦·Î ¼¼¼ÇÀ» Á¾·á ½ÃÄÑÁà¾ß ÇÑ´Ù.

±×·³ Ŭ¶óÀÌ¾ðÆ® ÇÁ·Î±×·¥ÀÌ ¾î¶² ÀÌÀ¯·Î Á×¾î¹ö·È´Ù¸é. °ú¿¬ Á¤»óÁ¾·á°¡ ÀϾ´ÂÁö¿¡ ´ëÇØ¼­ ¾Ë¾Æº¸µµ·Ï ÇϰڴÙ. Ŭ¶óÀÌ¾ðÆ® ÇÁ·Î±×·¥ÀÌ Á×¾úÀ»¶§ Á¤»óÁ¾·á°¡ ÀϾ·Á¸é Ä¿³Î¿¡¼­ ÇÁ·Î¼¼½º¸¦ Á¤¸®ÇÒ¶§ ¿­¸° Æ÷Æ®µµ ÇÔ²² Á¤¸®ÇÏ¸é µÉ°ÍÀÌ´Ù.

´ÙÇàÈ÷µµ ºñÁ¤»óÀûÀÎ ³×Æ®¿öÅ© ¾îÇø®ÄÉÀ̼ÇÀÇ Á¾·á°¡ ÀϾ°æ¿ì Ä¿³Î¿¡¼­ ¾Ë¾Æ¼­ ó¸®ÇØÁØ´Ù. º¸Åë ¾îÇø®ÄÉÀ̼ÇÀÌ Á¾·áµÇ´Â °æ¿ì´Â SIGNAL À» ¹Þ¾ÒÀ»°æ¿ì°¡ µÈ´Ù. SIGINT, SIGSEGV, SIGBUS, SIGKILL µîÀÌ ´ëÇ¥ÀûÀÎ ¾îÇø®ÄÉÀÌ¼Ç Á¾·á¿Í °ü·ÃµÈ ½Ã±×³ÎµéÀÌ´Ù. ÀÌ·¯ÇÑ ½Ã±×³ÎµéÀÌ ¹ß»ýÇØ¼­ ÇÁ·Î¼¼½º°¡ Á¾·áÇÏ°Ô µÇ¸é, Ä¿³Î¿¡¼­´Â ÇØ´çÇÁ·Î¼¼½ºÀÇ ¸ðµç ÀÚ¿øÀ» ÇØÁ¦ ½ÃŰ°Ô µÈ´Ù. À̵é ÀÚ¿ø¿¡´Â ¼ÒÄÏ ÆÄÀÏ ÁöÁ¤ÀÚµµ Æ÷ÇԵȴÙ. ´ÙÀ½Àº echo_client ·Î echo_server ¿¡ Á¢±ÙÇÑÈÄ CTRL+C ¸¦ ÀÔ·ÂÇØ¼­ echo_client ¸¦ °­Á¦ Á¾·á½ÃŲ °æ¿ìÀÇ tcpdump ³»¿ëÀÌ´Ù.


°á°ú¸¦ º¸¸é ¾Ë°ÚÁö¸¸ close ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ Á¤»óÁ¾·á¸¦ Çϴ°æ¿ì¿Í ¸¶Âù°¡Áö·Î FIN-ACK ¸Þ½ÃÁö°¡ Á¦´ë·Î Àü´ÞµÇ°í ÀÖÀ½À» ¾Ë¼ö ÀÖ´Ù. ÀÌ´Â ¼ÒÄÏÀÌ À¯´Ð½º Ä¿³ÎÀÇ ÀϺηΠÀÛµ¿Çϸ鼭, Ä¿³Î¿¡¼­ ÇÁ·Î¼¼½º¸¦ Á¤¸®ÇÒ¶§ ¼ÒÄÏÀ» Á¤»óÁ¾·á¸¦ ½ÃÄÑÁֱ⠶§¹®ÀÌ´Ù.

°á·ÐÀûÀ¸·Î ¸»ÇÏÀÚ¸é ºñ·Ï ÇÁ·Î±×·¥ÀÌ ºñÁ¤»óÁ¾·á µÇ´õ¶óµµ, ¼­¹ö/Ŭ¶óÀ̾ðÆ®Ãø ÇÁ·Î±×·¥¿¡¼­ ¿¡·¯Ã³¸®¸¸ Á¦´ë·Î ÇØÁÖ´Â Á¤µµ·Î - Àбâ/¾²±â¿¡ ¿¡·¯°¡ ÀÖÀ»°æ¿ì ÇØ´ç ¼ÒÄÏÁöÁ¤ÀÚ¸¦ close() ½ÃÄÑÁÖ´Â - ºñÁ¤»óÁ¾·á¿¡ À¯¿¬ÇÏ°Ô ´ëóÇÒ¼ö ÀÖÀ½À» ¾Ë¼ö ÀÖ´Ù.

3.2 ³×Æ®¿öÅ© ´ÜÀý

±×·¯³ª ³×Æ®¿öÅ© ´ÜÀýÀº "¾îÇø®ÄÉÀ̼ÇÀÇ ºñÁ¤»ó Á¾·á" ¿Í´Â ¾à°£ ´Ù¸£´Ù. ¸¸¾à Ŭ¶óÀÌ¾ðÆ®°¡ ¼­¹ö·ÎºÎÅÍÀÇ µ¥ÀÌŸ¸¦ ±â´Ù¸®´ÂÁß¿¡(read) ³×Æ®¿öÅ© ´ÜÀýÀÌ ÀϾ´Ù¸é, Ŭ¶óÀÌ¾ðÆ®´Â µµÂøÇÏÁö ¾ÊÀ» ¼­¹öµ¥ÀÌŸ¸¦ ±â´Ù¸®¸é¼­ ¿µ¿øÈ÷ ºÀ¼âµÉ¼ö ÀÖ´Ù.

¸¸¾à Ŭ¶óÀÌ¾ðÆ®°¡ ¼­¹ö·Î µ¥ÀÌŸ¸¦ ¾²·Á°í Çϴµ¥ ´ÜÀýÀÌ ÀϾ¸é ¾î¶²ÀÏÀÌ ¹ú¾îÁú±î? 2°¡Áö °æ¿ì¸¦ »ý°¢Çغ¼¼ö Àִµ¥ ¿ì¼±Àº Ŭ¶óÀÌ¾ðÆ® ¾îÇø®ÄÉÀ̼ÇÀ» »ý¼º½Ã۱â ÀÌÀü¿¡ ÀÌ¹Ì ³×Æ®¿öÅ©ÀÌ ´ÜÀýµÈ »óÅ¿Í, ¼¼¼ÇÀÌ ¸Î¾îÁø ´ÙÀ½ ³×Æ®¿öÅ©ÀÌ ´ÜÀýµÈ »óÅÂÀÌ´Ù. 2°³ÀÇ °æ¿ì ¸ðµÎ µ¿ÀÏÇÑ °á°ú¸¦ º¸¿©Áִµ¥, ÇØ´ç¿µ¿ª¿¡¼­ ¿µ¿øÈ÷ ºÀ¼âµÇ°Ô µÈ´Ù.

¸¸¾à ³×Æ®¿öÅ© ¿¬°áÀÌ ²÷¾îÁ® ÀÖ´Â »óÅ¿¡¼­ Ŭ¶óÀÌ¾ðÆ®¸¦ ½ÇÇà½Ãų °æ¿ì Ŭ¶óÀÌ¾ðÆ®´Â 3¹ø ¾Ç¼ö±â¹ýÀ» ÀÌ¿ëÇØ¼­ ¼­¹ö¿Í ¼¼¼ÇÀ» ¸Î°íÀÚ ÇÒ°ÍÀÌ´Ù. ±×·¸´Ù¸é ´ÙÀ½°ú °°Àº SYN ÆÐŶÀ» ¸¸µé¾î º¸³¾°ÍÀÌ´Ù.


±×·¯³ª ³×Æ®¿öÅ©Àº ´ÜÀýµÈ »óÅÂÀ̱⠶§¹®¿¡ °áÄÚ ÀÌ SYN ÆÐŶ¿¡ ´ëÇÑ ACK ÆÐŶÀº µµÂøÇÏÁö ¾ÊÀ»°ÍÀ̸ç, Ŭ¶óÀÌ¾ðÆ®´Â SYN(ACK) ÆÐŶÀ» ±â´Ù¸®¸é¼­ ºÀ¼âµÈ´Ù. Á¤È®ÇÏ°Ô ±¸ÇöÀ» ¼³¸íÇÏÀÚ¸é Ä¿³ÎÀº SYN ¿¡ ´ëÇÑ SYN(ACK)°¡ µµÂøÇÏÁö ¾ÊÀ»°æ¿ì ÀÏÁ¤½Ã°£¸¶´Ù ÀçÀü¼ÛÇϵµ·Ï µÇ¾î ÀÖ´Ù. ÀçÀü¼Û °£°ÝÀº ¿î¿µÃ¼Á¦ ¸¶´Ù ´Ù¸¦¼ö Àִµ¥ ´ë·« 5ÃÊ Á¤µµÀÌ´Ù.

³×Æ®¿öÅ© ´ÜÀýÀ» Å×½ºÆ®ÇÒ¼ö ÀÖ´Â °¡Àå °£´ÜÇÑ ¹æ¹ýÀº ¼­¹ö/Ŭ¶óÀÌ¾ðÆ® Åë½ÅÁß ·£¼±À» »Ì¾Æ¹ö¸®´Â °ÍÀÌ´Ù. ½ÇÁ¦ À§ÀÇ Å×½ºÆ®µéµµ ·£¼±À» »Ì¾Æ¹ö¸®´Â ¹æ¹ýÀ» ÀÌ¿ëÇØ¼­ Å×½ºÆ® Çß´Ù.

3.3 ¾îÇø®ÄÉÀ̼ÇÀÇ ºñÁ¤»óÀÛµ¿

ÄÚµùÀÌ À߸øµÇ¾î¼­ µ¥ÀÌŸ¸¦ ¹Þ¾ÒÀ½¿¡µµ ºÒ±¸ÇÏ°í µ¥ÀÌŸ¸¦ Àü¼ÛÇÏÁö ¾Ê´Â °æ¿ì, ȤÀº µ¥ÀÌŸ¸¦ ÀÐÁö ¾Ê´Â °æ¿ìµîÀÌ Æ÷ÇԵȴÙ. À̰æ¿ì¿¡´Â SYN-ACK ÆÐŶÀÌ ¼­·Î Á¤È®È÷ Àü´ÞµÇÁö¸¸ Á¦´ë·ÎµÈ Åë½Å°á°ú¸¦ ±â¾àÇÒ¼ö ¾ø°ÔµÇ¸ç, ¿µ¿øÈ÷ ºÀ¼âµÉ¼öµµ ÀÖ´Ù.

4 ¹®Á¦ ÇØ°á

4.1 ºñÁ¤»óÁ¾·á

ºñÁ¤»ó Á¾·áÀÇ °æ¿ì À­Àå¿¡¼­ º¸¾Ò´Ù½ÃÇÇ, ¿­¸° ¼ÒÄÏ¿¡ ´ëÇØ¼­ ¾Ë¾Æ¼­ Ä¿³Î¿¡¼­ Á¤¸®ÇØ ÁÜÀ¸·Î ¿¡·¯Ã³¸®¸¸ ½Å°æ½áÁÖ¸é ¹®Á¦°¡ ¾ø´Ù. ¾ÆÁÖ ½ÉÇÃÇÏ´Ù. ÀÌ°Ç ¼³¸íÇÒ Çʿ䰡 ¾øÀ»°Í °°´Ù.

4.2 ³×Æ®¿öÅ© ´ÜÀý

read/writeÇÔ¼ö¿¡ ´ëÇÑ ¿¡·¯Ã³¸®·Î ¾Ë¾Æ³¾¼ö ¾ø´Â ³×Æ®¿öÅ©´ÜÀý°ú °°Àº ¹®Á¦¿¡ °¡Àå ³Î¸® »ç¿ëµÇ´Â ¹æ¹ýÀº ÇØ´ç ½Ã½ºÅÛÈ£Ãâ¿¡ Time Out À» ÁÖ´Â ¹æ¹ýÀÌ´Ù. À̹æ¹ýÀº ÇØ´ç ½Ã½ºÅÛÄÝ¿¡ ´ëÇØ¼­ ÀÏÁ¤ ½Ã°£µ¿¾È ÀÀ´äÀÌ ¾øÀ¸¸é ¿¡·¯°¡ ¹ß»ýÇѰÍÀ¸·Î ÆÇ´ÜÇÏ°í ¿¬°áÀ» ²÷´Â´Ù. ÀÌ ¹æ¹ýÀº ºñ´Ü ³×Æ®¿öÅ©´ÜÀý°ú °°Àº ¹®Á¦ ¿Ü¿¡µµ, ¿¬°áÀº Çϰí ÀÖÀ¸³ª ¿À·£½Ã°£µ¿¾È ¾Æ¹«·± Àϵµ ÇÏÁö ¾Ê´Â Ŭ¶óÀ̾ðÆ®ÀÇ ¿¬°áÀ» ²÷±â À§ÇÑ ¿ëµµ µîÀ¸·Îµµ »ç¿ëÇÑ´Ù.

Time Out ¸¦ ÁÖ´Â °¡Àå °£´ÜÇÑ ¹æ¹ýÀº alarmÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ SIGALRM À» ¹ß»ý½ÃŰ´Â ¹æ¹ýÀÌ´Ù. ¶Ç´Ù¸¥ ¹æ¹ýÀ¸·Î´Â select(2) ³ª poll(2)¿Í °°Àº ÀÔÃâ·Â ´ÙÁßÈ­ ÇÔ¼ö¸¦ ÀÌ¿ëÇÑ ¹æ¹ýÀÌ´Ù.

4.2.1 alarm ÇÔ¼öÀÇ ÀÌ¿ë

µ¥ÀÌŸ¸¦ Àбâ Àü¿¡ alarm(2)ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ÀÏÁ¤½Ã°£µ¿¾È ÀÔ·ÂÀÌ ¾øÀ¸¸é SIGALRM ÀÌ Àü´ÞµÇ°Ô ÇÑ´Ù. ¸¸¾à SIGALRM ÀÌ Àü´ÞµÇ¸é ÇöÀç »óÅÂ(read) ¿¡ Interrupt °¡ Àü´ÞµÇ°Ô ÇÑ´Ù. ±×·¯¸é read ÇÔ¼ö´Â Interrupt °¡ Àü´ÞµÇ¾úÀ½À» °¨ÁöÇÏ°í ¸®ÅϵǴµ¥, À̶§ close ÇÔ¼öµîÀ» ÀÌ¿ëÇØ¼­ ¿¬°áÀ» Á¾·á½ÃŰ¸é µÈ´Ù.
// signal ¼³Á¤ 
// SIGALRM ÀÌ ºÒ¸®¿öÁö¸é ÇÁ·Î¼¼½º¿¡°Ô  
// interrupt °¡ Àü´ÞµÇµµ·Ï ¼³Á¤ÇÑ´Ù.  
signal ¼³Á¤ SIGALRM: 
 
// 10 ÃÊÈÄ¿¡ SIGALRM ÀÌ Àü´ÞµÇµµ·Ï ¼¼ÆÃ 
alarm(10); 
if (read(...) < 0) 
{ 
    // ¸¸¾à Interrupt ¸¦ ¹Þ°í read ÇÔ¼ö°¡ ¸®ÅϵǾúÀ»°æ¿ì  
    if (errno == EINTR) 
    { 
        // close ½Ã۴µîÀÇ ÀÛ¾÷À» ÇÑ´Ù.  
        close(); 
        .... 
    } 
} 
 
À§ ±¸ÇöÀÇ ÇÙ½ÉÀº SIGALRM¿¡ ´ëÇÑ interrupt°¡ ÇÁ·Î¼¼½º·Î Àü´ÞµÇ°Ô ÇÏ´Â ºÎºÐÀÌ´Ù. ¶ÇÇÑ read, write µîÀÇ ÇÔ¼ö°¡ Interrupt ¸¦ ¹Þ¾Æ¼­ ¸®ÅϵǾúÀ»°æ¿ì¸¦ ó¸®Çϱâ À§ÇÑ Äڵ尡 Ãß°¡µÈ´Ù. À̵é ÇÔ¼ö´Â Interrupt ¸¦ ¹Þ°í ¸®ÅϵǾúÀ»°æ¿ì errno °ªÀ» EINTR ·Î ¼³Á¤ÇÔÀ¸·Î errno °ªÀ» Çѹø¸¸ °Ë»çÇØÁÖ¸é ¹®Á¦ ¾øÀÌ Ã³¸® °¡´ÉÇÏ´Ù. À̵é ÇÔ¼ö¿¡ ´ëÇÑ man ÆäÀÌÁö¸¦ È®ÀÎÇØº¸¸é Interrupt ¿Í °ü·ÃµÈ ³»¿ëµéÀ» º¼¼ö ÀÖ´Ù.

´ÙÀ½Àº echo_server.c¸¦ alarmÇÔ¼ö¸¦ ÀÌ¿ë ÇØ¼­ Time outÀ» Á¤ÀÇÇÒ¼ö ÀÖµµ·Ï ¼öÁ¤ÇÑ ÄÚµå´Ù.

#include <unistd.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <sys/socket.h> 
#include <sys/stat.h> 
#include <arpa/inet.h>  
#include <stdio.h> 
#include <string.h> 
#include <signal.h> 
 
// ½Ã±×³Î Çڵ鷯ÀÌ´Ù. ÇÏ´ÂÀÏÀº ¾Æ¹«°Íµµ ¾ø´Ù.   
static void sig_handler(int signo) 
{ 
    return; 
} 
int main(int argc, char **argv) 
{ 
    int server_sockfd, client_sockfd;  
    int client_len, n; 
    char buf[80]; 
    struct sockaddr_in clientaddr, serveraddr; 
 
    // signal ¼³Á¤ 
    struct sigaction sigact, oldact; 
    sigact.sa_handler = sig_handler; 
    sigemptyset(&sigact.sa_mask); 
    sigact.sa_flags = 0; 
    // ¹Ù·Î À̺κÐÀÌ SIGNAL À» ¹Þ¾ÒÀ»¶§  
    // Interrupt °¡ ¹ß»ýÇϵµ·Ï ¼³Á¤ÇÏ´Â ºÎºÐÀÌ´Ù.   
    sigact.sa_flags |= SA_INTERRUPT; 
 
    if (sigaction(SIGALRM, &sigact, &oldact) < 0) 
    { 
        perror("sigaction error : "); 
        exit(0); 
    } 
 
    client_len = sizeof(clientaddr); 
 
    if ((server_sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) 
    { 
        perror("socket error : "); 
        exit(0); 
    } 
    bzero(&serveraddr, sizeof(serveraddr)); 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    serveraddr.sin_port = htons(atoi(argv[1])); 
 
    bind (server_sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)); 
    listen(server_sockfd, 5); 
 
    while(1) 
    { 
        memset(buf, 0x00, 80); 
        client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr,  
                            &client_len); 
        printf("Accept ok read data\n"); 
       
        // alarm À» 5ÃÊ·Î ¼³Á¤Çß´Ù. 
        alarm(5); 
        if ((n = read(client_sockfd, buf, 80)) <= 0)  
        { 
            // ¸¸¾à 5Ãʵ¿¾È read °¡ ¸®ÅÏÀÌ ¾ÈµÈ´Ù¸é 
            // SIGALRM ÀÌ ¹ß»ýÇϰí read ¿¡ Interrupt °¡ ¹ß»ýÇ졒  
            // read ´Â errno ¸¦ EINTR ·Î ¼³Á¤ÇÏ°í ¸®ÅÏÇÏ°Ô µÈ´Ù.  
            if (errno == EINTR) 
            { 
                printf ("signal Interrupt\n"); 
            } 
            alarm(0); 
            usleep(10); 
            close(client_sockfd); 
            continue; 
        } 
 
        alarm(0); 
        if (write(client_sockfd, buf, 80) <=0) 
        { 
            perror("write error : "); 
            close(client_sockfd); 
        } 
        close(client_sockfd); 
    } 
} 
 
ÇÑ 10ÁÙ Ãß°¡ Á¤µµ·Î ¾î·ÆÁö ¾Ê°Ô ±¸Çö°¡´ÉÇÔÀ» ¾Ë¼ö ÀÖ´Ù. ±×·¯³ª alarmÇÔ¼ö¸¦ ÀÌ¿ëÇÑ Time out ÀÇ ±¸ÇöÀº º¹ÀâÇÑ Äڵ忡´Â »ç¿ëÇÏ´Â°É ±ÇÀåÇÏÁö ¾Ê´Â´Ù. SIGALRM ÀÇ °æ¿ì´Â ´ÜÁö alarm¿¡¼­¸¸ ¹ß»ý½ÃŰ´Â°Ô ¾Æ´Ï°í ´Ù¸¥ ¿©·¯°¡Áö ÇÔ¼öµé¿¡¼­µµ »ç¿ëÇÏ´Â °æ¿ì°¡ Àִµ¥, ÀÌ·²°æ¿ì ÀÛµ¿ÇÏÁö ¾ÊÀ»¼ö Àֱ⠶§¹®ÀÌ´Ù. ¹°·Ð Á¦´ë·Î ½Å°æÀ» ½áÁÖ¸é µÇ±ä ÇϰÚÁö¸¸ ´ë±â¿­ÀÌ Á¸ÀçÇÏÁö ¾Ê´Â´Ù´Â ½Ã±×³ÎÀÇ Æ¯¼º»ó º¹ÀâÇÑ Äڵ忡 Àû¿ë½ÃŰ±â¿¡´Â ¹®Á¦°¡ µû¸¥´Ù.

4.2.2 select/poll ÀÇ ÀÌ¿ë

select/poll Àº ÀÔÃâ·Â ´ÙÁßÈ­¸¦ À§ÇÑ ¸ñÀûÀ¸·Î ÁÖ·Î »ç¿ëµÈ´Ù. ±×·¯³ª À̵é ÇÔ¼öÀÇ °æ¿ì ½º½º·Î°¡ Time out À» °áÁ¤Çϱâ À§ÇÑ ¹æ¹ýÀ» Á¦°øÇÔÀ¸·Î ºñ·Ï ÀÔÃâ·Â´ÙÁßÈ­ÀÇ ¸ñÀûÀÌ ¾Æ´Ñ ´Ü¼øÇÑ Time out °áÁ¤À» À§Çؼ­µµ À¯¿ëÇÏ°Ô »ç¿ëÇÒ¼ö ÀÖ´Ù.

#include <unistd.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <sys/socket.h> 
#include <sys/stat.h> 
#include <arpa/inet.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/time.h> 
#include <sys/types.h> 
 
int main(int argc, char **argv) 
{ 
    int server_sockfd, client_sockfd; 
    int client_len, n; 
    int state; 
    char buf[80]; 
    struct sockaddr_in clientaddr, serveraddr; 
 
    // select time out ¼³ÀúÀ» À§ÇÑ timeval ±¸Á¶Ã¼     
    struct timeval tv; 
    fd_set readfds; 
 
    client_len = sizeof(clientaddr); 
    if ((server_sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) 
    { 
        perror("socket error : "); 
        exit(0); 
    } 
    bzero(&serveraddr, sizeof(serveraddr)); 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    serveraddr.sin_port = htons(atoi(argv[1])); 
 
    bind (server_sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)); 
    listen(server_sockfd, 5); 
 
    while(1) 
    { 
        memset(buf, 0x00, 80); 
        client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr, 
                            &client_len); 
        // client_sockfd ÀÇ ÀԷ°˻縦 À§Çؼ­  
        // fd_set ¿¡ µî·ÏÇÑ´Ù.  
        FD_ZERO(&readfds); 
        FD_SET(client_sockfd, &readfds); 
        // ¾à 5Ãʰ£ ±â´Ù¸°´Ù.  
        tv.tv_sec = 5; 
        tv.tv_usec = 10; 
 
        // ÀÔ·ÂÀÌ ÀÖ´ÂÁö ±â´Ù¸°´Ù.  
        state = select(client_sockfd+1, &readfds, 
                        (fd_set *)0, (fd_set *)0, &tv); 
        switch(state) 
        { 
            case -1: 
                perror("select error :"); 
                exit(0); 
            // ¸¸¾à 5Ãʾȿ¡ ¾Æ¹«·± ÀÔ·ÂÀÌ ¾ø¾ú´Ù¸é  
            // Time out ¹ß»ý»óȲÀÌ´Ù.  
            case 0: 
                printf("Time out error\n"); 
                break; 
            // 5Ãʾȿ¡ ÀÔ·ÂÀÌ µé¾î¿ÔÀ»°æ¿ì ó¸®ÇÑ´Ù.  
            default: 
                if ((n = read(client_sockfd, buf, 80)) <= 0) 
                { 
                    perror("read error : "); 
                    usleep(10); 
                    break; 
                } 
                if (write(client_sockfd, buf, 80) <=0) 
                { 
                    perror("write error : "); 
                    break; 
                } 
                break; 
        } 
        close(client_sockfd); 
    } 
} 
 

¿©±â¿¡¼­´Â select ¸¸À» ¿¹·Î µé¾ú´Âµ¥ poll ·Îµµ ºñ½ÁÇÏ°Ô ±¸Çö °¡´ÉÇÏ´Ù. select ¸¦ ÀÌ¿ëÇÒ°æ¿ì alarm() ¿¡ ºñÇØ¼­ ½Å·Ú¼ºÀÖ°Ô ¼­¹ö¸¦ ±¸¼ºÇÏ´Â°Ô °¡´ÉÇÏ´Ù. ±×·¯³ª ÀÔÃâ·Â´ÙÁßÈ­ + time out °Ë»ç¿ëÀ¸·Î »ç¿ëÇϱ⿡´Â Àû´çÇÏÁö °¡ ¾Ê´Ù. À§¿¡¼­ÀÇ °æ¿ì¿¡´Â ´ÜÁö ÇϳªÀÇ ¿¬°á¿¡ ´ëÇØ¼­¸¸ time out À» °Ë»çÇߴµ¥, ¸¸¾à ¿©·¯°³ÀÇ ¿¬°áÀ» ¹Þ¾Æµé¿©¼­ ÀÔÃâ·Â ´ÙÁßÈ­¸¦ ÇÒ°æ¿ì select ´Â ¸ðµç ÀԷ¿¡ ´ëÇÑ time out ¸¸À» °Ë»çÇÔÀ¸·Î, °¢°¢ÀÇ °³º°ÀûÀÎ ÀԷ¿¡ ´ëÇØ¼­´Â time out °á°ú¸¦ ¾Ë¼ö ¾ø±â ¶§¹®ÀÌ´Ù.

4.3 ¿¬°á ¼ÒÄÏ Time out ó¸®

Ŭ¶óÀÌ¾ðÆ®¿¡¼­ ¼­¹ö·Î ¿¬°á ÇÒ ¶§ÀÇ Time out 󸮿¡ ´ëÇØ¼­ ¾Ë¾Æº¸ÀÚ. selectÇÔ¼ö¸¸À» ÀÌ¿ëÇØ¼­ ó¸®ÇÒ ¼ö´Â ¾ø´Ù. connect ÇÔ¼ö¿¡¼­ ºÀ¼âµÇ±â ¶§¹®ÀÌ´Ù. °á±¹ ¼ÒÄÏÀ» ºñ ºÀ¼â·Î ¸¸µç´ÙÀ½ selectÇÔ¼ö·Î ±â´Ù·Á¾ß ÇÑ´Ù.

´ÙÀ½°ú °°Àº ¹æ½ÄÀ¸·Î connect ŸÀӾƿôÀ» ±¸ÇöÇÒ °ÍÀÌ´Ù. fcntl(2) ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ µè±â¼ÒÄÏÀ» ºñ ºÀ¼â ¼ÒÄÏÀ¸·Î ¸¸µç´Ù.ÀÌÁ¦ connectÇÔ¼ö¸¦ È£ÃâÇÏ¸é ¹Ù·Î ¸®Å쵃 °ÍÀÌ´Ù. select(2)¸¦ ÀÌ¿ëÇØ¼­ timeoutÀ» üũÇϵµ·Ï ÇÑ´Ù. timeout üũ°¡ ³¡³­ µÚ¿¡´Â ¼ÒÄÏÀ» ¿ø·¡ÀÇ blocking »óÅ·ΠµÇµ¹¸°´Ù.

#include <sys/stat.h>  
#include <arpa/inet.h>  
#include <stdio.h>  
#include <string.h>  
#include <unistd.h>  
#include <fcntl.h>  
#include <errno.h>  
  
int ConnectWait(int sockfd, struct sockaddr *saddr, int addrsize, int sec)  
{  
    int newSockStat;  
    int orgSockStat;  
    int res, n;  
    fd_set  rset, wset;  
    struct timeval tval;  
  
    int error = 0;  
    int esize;  
  
    if ( (newSockStat = fcntl(sockfd, F_GETFL, NULL)) < 0 )   
    {  
        perror("F_GETFL error");  
        return -1;  
    }  
  
    orgSockStat = newSockStat;  
    newSockStat |= O_NONBLOCK;  
  
    // Non blocking »óÅ·Π¸¸µç´Ù.   
    if(fcntl(sockfd, F_SETFL, newSockStat) < 0)  
    {  
        perror("F_SETLF error");  
        return -1;  
    }  
  
    // ¿¬°áÀ» ±â´Ù¸°´Ù.  
    // Non blocking »óÅÂÀ̹ǷΠ¹Ù·Î ¸®ÅÏÇÑ´Ù.  
    if((res = connect(sockfd, saddr, addrsize)) < 0)  
    {  
        if (errno != EINPROGRESS)  
            return -1;  
    }  
  
    printf("RES : %d\n", res);  
    // Áï½Ã ¿¬°áÀÌ ¼º°øÇßÀ» °æ¿ì ¼ÒÄÏÀ» ¿ø·¡ »óÅ·ΠµÇµ¹¸®°í ¸®ÅÏÇÑ´Ù.   
    if (res == 0)  
    {  
        printf("Connect Success\n");  
        fcntl(sockfd, F_SETFL, orgSockStat);  
        return 1;  
    }  
  
    FD_ZERO(&rset);  
    FD_SET(sockfd, &rset);  
    wset = rset;  
  
    tval.tv_sec        = sec;      
    tval.tv_usec    = 0;  
  
    if ( (n = select(sockfd+1, &rset, &wset, NULL, NULL)) == 0)  
    {  
        // timeout  
        errno = ETIMEDOUT;      
        return -1;  
    }  
  
    // Àаųª ¾´ µ¥ÀÌÅͰ¡ ÀÖ´ÂÁö °Ë»çÇÑ´Ù.   
    if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset) )  
    {  
        printf("Read data\n");  
        esize = sizeof(int);  
        if ((n = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&esize)) < 0)  
            return -1;  
    }  
    else  
    {  
        perror("Socket Not Set");  
        return -1;  
    }  
  
  
    fcntl(sockfd, F_SETFL, orgSockStat);  
    if(error)  
    {  
        errno = error;  
        perror("Socket");  
        return -1;  
    }  
  
    return 1;  
}  
  
int main(int argc, char **argv)  
{  
    struct sockaddr_in serveraddr;  
    int sockfd;  
    int len;  
  
    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )  
    {  
        perror("error");  
        return 1;  
    }  
    serveraddr.sin_family = AF_INET;  
    serveraddr.sin_family = AF_INET;  
    serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");  
    serveraddr.sin_port = htons(atoi(argv[1]));  
  
    len = sizeof(serveraddr);  
  
    if (ConnectWait(sockfd, (struct sockaddr *)&serveraddr, len, 5) < 0)  
    {  
        perror("error");  
    }  
    else  
    {  
        printf("Connect Success\n");  
    }  
    while(1)  
    {  
        sleep(1);  
    }  
    close(sockfd);  
}  
 

http://www.developerweb.net/forum/showthread.php?p=13486

category_network
programing
category__5

Cache Error
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù.