ÃÑ ÆäÀÌÁö ¼ö : 3224
![]()
|
Facebook Joinc ±×·ì
Joinc QA »çÀÌÆ®
![]()
Tweet
joinc´Â Firefox¿Í chrome¿¡¼ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù. 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); } } #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); } } 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); } |
|
|
|
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù. |
|