BSD Socket Programming
1. SocketÀÇ ±âº» °³³ä 1-1. SocketÀÇ Á¤ÀÇ 1-2. Socket Descript 2. ÇÁ·Î±×·¥ µ¿ÀÛ ¼³¸í 2-1. TCP Åë½Å 2-2. UDP Åë½Å 3. Socket ProgrammingÀÇ ±¸¼º¿ä¼Ò 3-1. ¼ÒÄÏÀÎÅÍÆäÀ̽º¿¡¼ »ç¿ëÇÏ´Â µ¥ÀÌÅÍ Å¸ÀÔ 3-2. struct socketaddr_in 3-3. struct in_addr 3-4. htons() 3-5. socket() 3-6. bind() 3-7. connect() 3-8. listen() 3-9. accept() 3-10. sedn(), recv() 4. ÇÁ·Î±×·¥ ¼Ò½º ¼³¸í 4-1. server.c 4-2. client.c 5. ½ÇÇà ȯ°æ 6. CASE ¿¬±¸ 6-1. concurrent ¼ºñ½º ¹æ½Ä¿¡ ÀÇÇØ Åë½ÅÇÒ °æ¿ì? (TCP) 6-2. interative ¼ºñ½º ¹æ½Ä¿¡ ÀÇÇØ Åë½ÅÇÒ °æ¿ì? (TCP) 6-3. Bind ÇÔ¼öÀÇ ±â´É(TCP Socket) 1) Server´Â ¹Ýµå½Ã Port BindingÀÌ ÇÊ¿äÇÑ°¡? 2) Client°¡ Port¸¦ Binding ÇÏ¸é ¾î¶°ÇÑ°¡? 6-4. Listen ÇÔ¼öÀÇ ±â´É(TCP Socket) 1) Server°¡ listen()À» ºüÆ®¸° °æ¿ì? 2) listen ÇÔ¼öÀÇ Queue size¸¦ 1·Î ÁöÁ¤Çϸé? 6-5. Server°¡ accept¸¦ ÇÏÁö ¾ÊÀº °æ¿ì? (TCP) 6-6. Blocking Operation¿¡ ´ëÇÏ¿© ¾Ë¾Æº¸ÀÚ (TCP) 1) send()¿Í recv()´Â ¾î¶² mode·Î µ¿ÀÛÇϴ°¡ ? 2) accept()¿Í connect()´Â ¾î¶² mode·Î µ¿ÀÛÇϴ°¡ ? 6-7. º¹¼öÀÇ Åë½Å·Î¸¦ ¿¾úÀ» ¶§ ? (TCP) 6-8. UDP Socket Åë½ÅÀÇ Æ¯Â¡°ú ±âº» ÀýÂ÷¸¦ ¾Ë¾Æº¸ÀÚ 6-9. UDP Socket Åë½Å¿¡¼ ¿À·ùÁ¦¾î¸¦ È®ÀÎÇϱâ À§ÇØ ´ë¿ë·®ÀÇ data¸¦ º¸³»º¸ÀÚ. - 82 6-10. Bind Error´Â ¾ðÁ¦ ¹ß»ýÇϴ°¡ ? (TCP) 1) closeÇÏÁö ¾Ê¾ÒÀ» ¶§ Bind Error°¡ ¹ß»ýÇϴ°¡ ? 2) exitÇÏÁö ¾Ê¾ÒÀ» ¶§ Bind Error°¡ ¹ß»ýÇϴ°¡ ? 6-11. Server³ª Client°¡ Á×´Â °æ¿ì ? (TCP) 1) ServerÀÇ Child Process°¡ Á×´Â °æ¿ì ? 2) ServerÀÇ Parent Process°¡ Á×´Â °æ¿ì ? 3) Client Process°¡ Á×´Â °æ¿ì ? 6-12. Ç¥ÁØ ÀÎÅÍ³Ý ¼ºñ½º µî·Ï ¹æ¹ý 1) ¼Ò½º ÆÄÀÏ Ã·ºÎ exhoex.c, exhoexd.c
1. SocketÀÇ ±âº»°³³ä 1-1. ¼ÒÄÏÀÇ Á¤ÀÇ
¼ÒÄÏÀº 1982³â BSD(Berkeley Software Distribution) UNIX 4.1¿¡¼ óÀ½ ¼Ò°³µÇ¾úÀ¸¸ç ÇöÀç ³Î¸® »ç¿ëµÇ´Â °ÍÀº 1986³â BSD UNIX 4.3¿¡¼ °³Á¤µÈ °ÍÀÌ´Ù. ¼ÒÄÏÀº ¼ÒÇÁÆ®¿þ¾î·Î ÀÛ¼ºµÈ Åë½Å Á¢¼ÓÁ¡À̶ó°í ÇÒ ¼ö ÀÖ´Ù. ³×Æ®¿÷ ÀÀ¿ë ÇÁ·Î±×·¥Àº ¼ÒÄÏÀ» ÅëÇÏ¿© Åë½Å¸ÁÀ¸·Î µ¥ÀÌÅ͸¦ ¼Û¼ö½Å ÇÏ°Ô µÈ´Ù. ±×¸²1¿¡ ¼¼ °³ÀÇ ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ °¢°¢ ¼ÒÄÏÀ» ÅëÇÏ¿© TCP/IP¸¦ °øÀ¯ÇÏ°í ÀÖ´Â °ÍÀ» ³ªÅ¸³Â´Ù.
¼ÒÄÏÀº ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼ TCP/IP¸¦ ÀÌ¿ëÇϴ â±¸ ¿ªÇÒÀ» Çϸç ÀÀ¿ë ÇÁ·Î±×·¥°ú ¼ÒÄÏ »çÀÌÀÇ ÀÎÅÍÆäÀ̽º¸¦ ¼ÒÄÏ ÀÎÅÍÆäÀ̽º¶ó°í ÇÑ´Ù.
1-2. Socket Descriptor
UNIX¿¡¼ ÆÄÀÏÀ» OpenÇϸé int ŸÀÔÀÇ Á¤¼ö¸¦ returnÇϴµ¥ ÀÌ¿Í °°ÀÌ openÀÌ returnÇÑ Á¤¼ö¸¦ ÆÄÀϱâ¼úÀÚ(file descriptor)¶ó°í Çϸç ÇÁ·Î±×·¥¿¡¼ openµÈ ÆÄÀÏÀ» ¾×¼¼½ºÇÒ ¶§ ÀÌ ÆÄÀϱâ¼úÀÚ¸¦ »ç¿ëÇÏ°Ô µÈ´Ù. ÆÄÀϱâ¼úÀÚ´Â ±â¼úÀÚ Å×À̺í(descriptor table)ÀÇ index ¹øÈ£Àε¥(±×¸² 2 ÂüÁ¶), ±â¼úÀÚ Å×À̺íÀ̶õ ÇöÀç openµÇ¾î ÀÖ´Â ÆÄÀÏÀÇ °¢Á¾ Á¤º¸¸¦ Æ÷ÇÔÇÏ°í ÀÖ´Â ±¸Á¶Ã¼¸¦ °¡¸®Å°´Â Æ÷ÀÎÅ͵é·Î ±¸¼ºµÈ Å×À̺íÀÌ´Ù. ¿¹¸¦ µé¾î ÇÑ ÀÀ¿ë ÇÁ·Î±×·¥ ³»¿¡¼ 2°³ÀÇ ÆÄÀÏÀ» openÇϸé ÆÄÀϱâ¼úÀÚ´Â 3°ú 4°¡ ¹èÁ¤µÈ´Ù.
¡¡
ÇÁ·Î±×·¥¿¡¼ ¼ÒÄÏÀ» °³¼³Çϸé ÆÄÀϱâ¼úÀÚ¿Í ¶È°°Àº ±â´ÉÀ» ÇÏ´Â ¼ÒÄϱâ¼úÀÚ(socket descriptor)°¡ returnµÈ´Ù. ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼ ÀÌ ¼ÒÄÏÀ» ÅëÇÏ¿© ¸ñÀûÁö È£½ºÆ®¿Í ¿¬°áÀ» ¿ä±¸Çϰųª ÆÐŶÀ» ¼Û¼ö½ÅÇÒ ¶§ ÇØ´ç ¼ÒÄϱâ¼úÀÚ¸¦ »ç¿ëÇÏ°Ô µÈ´Ù(¼ÒÄϱâ¼úÀÚ¸¦ ¼ÒÄÏ ¹øÈ£¶ó°í ºÎ¸¥´Ù). UNIX¿¡¼´Â ÆÄÀϱâ¼úÀÚ¿Í ¼ÒÄϱâ¼úÀÚ°¡ °°Àº ±â¼úÀÚ Å×À̺íÀÇ index°¡ µÈ´Ù. Áï, ÆÄÀÏ°ú ¼ÒÄÏÀÌ ±â¼úÀÚ Å×À̺íÀ» °øÀ¯ÇÑ´Ù. ÇÑ ÇÁ·Î¼¼½º¿¡¼ ÆÄÀÏ open½Ã returnµÇ´Â ÆÄÀϱâ¼úÀÚ¿Í ¼ÒÄÏ Open½Ã returnµÇ´Â ¼ÒÄϱâ¼úÀÚÀÇ °ªÀº ¼·Î Áߺ¹µÈ °ÍÀÌ ¾ø°Ô µÈ´Ù. ±×¸² 2¿¡´Â µÎ °³ÀÇ ÆÄÀÏ°ú ÇÑ °³ÀÇ ¼ÒÄÏÀ» °³¼³ÇÏ¿´À» ¶§ÀÇ ±â¼úÀÚ Å×À̺í°ú ±â¼úÀÚ Å×À̺íÀÌ °¡¸®Å°´Â ÆÄÀÏ ¶Ç´Â ¼ÒÄÏ µ¥ÀÌÅÍ ±¸Á¶Ã¼¸¦ ³ªÅ¸³»°í ÀÖ´Ù. ±×¸² 2¿¡ ÀÀ¿ë ÇÁ·Î±×·¥°ú ¼ÒÄÏ ±×¸®°í TCP/IPÀÇ °ü°è¸¦ ±¸Ã¼ÀûÀ¸·Î ³ªÅ¸³Â´Ù. ³× °³ÀÇ ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ ¼ÒÄϹøÈ£·Î °¢°¢ 4, 3, 3, 3À» »ç¿ëÇÏ°í ÀÖ´Â °ÍÀ» ³ªÅ¸³Â´Ù(ÀÀ¿ë ÇÁ·Î±×·¥ 1Àº ÆÄÀÏÀ» Çϳª ¸ÕÀú ¿°í ÀÖÀ¸¹Ç·Î ¼ÒÄϹøÈ£°¡ 4°¡ µÈ °ÍÀÌ´Ù). ÇÑÆí ¼ÒÄϹøÈ£´Â ÀÀ¿ë ÇÁ·Î±×·¥ ³»¿¡¼ ¼ø¼´ë·Î ¹èÁ¤µÇ¸ç ±× ÇÁ·Î±×·¥ ³»¿¡¼¸¸ À¯ÀÏÇÏ°Ô ±¸ºÐµÇ¸é µÇ´Â °ÍÀ̹ǷΠ¼·Î ´Ù¸¥ ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼ °°Àº ¼ÒÄϹøÈ£¸¦ »ç¿ëÇÏ´Â °ÍÀº ¹®Á¦°¡ µÇÁö ¾Ê´Â´Ù. Æ÷Æ®¹øÈ£´Â TCP/IP°¡ Áö¿øÇÏ´Â »óÀ§ °èÃþÀÇ ÇÁ·Î¼¼½º¸¦ ±¸ºÐÇϱâ À§ÇÑ ¹øÈ£À̹ǷΠÇϳªÀÇ ÄÄÇ»ÅÍ ³»¿¡ ÀÖ´Â ÀÀ¿ë ÇÁ·Î¼¼½ºµéÀº ¹Ýµå½Ã ¼·Î ´Ù¸¥ Æ÷Æ®¹øÈ£¸¦ »ç¿ëÇÏ¿©¾ß ÇÑ´Ù. ±×¸² 3¿¡¼´Â ³× °³ÀÇ ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ 3000¹øºÎÅÍ 3003 ¹øÀÇ Æ÷Æ®¹øÈ£¸¦ »ç¿ëÇÏ´Â °ÍÀ» °¡Á¤ÇÏ¿´´Ù. ±×¸² 3¿¡¼ ¿¬°áÇü ¼ºñ½º´Â TCP°¡ ±×¸®°í ºñ¿¬°áÇü ¼ºñ½º´Â UDP°¡ °¢°¢ ó¸®ÇÏ´Â °ÍÀ» º¸¿´´Ù. IP ÁÖ¼Ò 192.203.144.11Àº ÀÌ ÄÄÇ»ÅÍ¿¡ ¹èÁ¤µÈ IP ÁÖ¼ÒÀε¥ ¿¹¸¦ µé¾î ¸ñÀûÁö IP ÁÖ¼Ò°¡ 192.203.144.11ÀÎ IP ÆÐŶÀº ¸ðµÎ ±×¸² 3ÀÇ ÄÄÇ»ÅÍ·Î Àü´ÞµÈ´Ù. ÀÌ ÆÐŶÀ» ¼ö½ÅÇÒ ÀÀ¿ë ÇÁ·Î±×·¥Àº TCP(¶Ç´Â UDP) Çì´õ¿¡ ÀÖ´Â 16ºñÆ®ÀÇ Æ÷Æ®¹øÈ£¸¦ ÂüÁ¶ÇÏ¿© ±¸ºÐÇÑ´Ù.
2. ÇÁ·Î±×·¥ µ¿ÀÛ ¼³¸í
2-1. TCP Åë½Å
2-1-1. Ư¡
- ¾ç¹æÇâÀÇ ½ºÆ®¸² Åë½Å ¼ºñ½º¸¦ Á¦°øÇÏ´Â ¿¬°áÀ§ÁÖÀÇ ½Å·Ú¼º ÀÖ´Â Åë½Å ÇÁ·ÎÅäÄÝÀÌ´Ù. - ´ëºÎºÐÀÇ ÀÎÅÍ³Ý ¾ÖÇø®ÄÉÀ̼ÇÀÌ »ç¿ëÇÑ´Ù. - IP ÇÁ·ÎÅäÄÝÀÇ ºñ½Å·ÚÀûÀÎ ¼ºñ½º¸¦ º¸¿ÏÇϱâ À§ÇØ, °¡»óÀÇ È¸¼±À» ¼³Á¤ÇÑ´Ù. - ÀÀ¿ë ÇÁ·Î±×·¥¿¡°Ô ½Å·Ú¼º ÀÖ´Â ¿¬°á¼º ¼ºñ½º¸¦ Á¦°øÇÑ´Ù.
2-1-2. TCP ÇÁ·ÎÅäÄÝÀÇ ¿ªÇÒ
- ÇÁ·Î¼¼½º°£ÀÇ ¿¬°áÀÇ ±¸Ãà°ú Àý´ÜÀ» ´ã´çÇÑ´Ù. - Àü¼Û ¹ÞÀº µ¥ÀÌÅ͸¦ ¼ø¼´ë·Î ¸ÂÃá´Ù. - ¾ç ³¡Á¡°£ÀÇ È帧À» Á¦¾îÇÑ´Ù.
2-1-3. Ŭ¶óÀ̾ðÆ®/¼¹öÀÇ µ¿ÀÛ
- Server ¨ç socket() ½Ã½ºÅÛ ÄÝ¿¡¼ ÆÄÀÏ µð½ºÅ©¸³ÅÍ¿Í ¼ÒÄÏ µð½ºÅ©¸³Å͸¦ ÇÒ´ç¹Þ´Â´Ù. ¨è bind()¿¡¼ ÀÚ½ÅÀÇ ÁÖ¼Ò¿Í Æ÷Æ®¸¦ ¼ÒÄÏ µð½ºÅ©¸³ÅÍ¿Í ¿¬°á½ÃŲ´Ù. ¨é listen()À» ÀÌ¿ëÇØ ¼¹ö°¡ µ¿½Ã¿¡ ¹ÞÀ» ¼ö Àִ Ŭ¶óÀ̾ðÆ®ÀÇ Á¢¼Ó¿äû ¼ö¸¦ ÁöÁ¤ÇÑ´Ù. ¨ê accept()¿¡¼ Ŭ¶óÀ̾ðÆ®ÀÇ request¸¦ ±â´Ù¸°´Ù. ¨ë request°¡ µé¾î¿À¸é connectÇÑ ÈÄ read()/write()¸¦ ÅëÇØ ÀÔÃâ·ÂÀ» ¼öÇàÇÑ´Ù.
- Client ¨ç connect()¿¡¼ ¼¹ö¿¡°Ô Á¢¼Ó request¸¦ º¸³½´Ù. ¨è request°¡ ¹Þ¾Æµé¿©Á® Á¢¼ÓÀÌ È®¸³µÈ´Ù. ¨é read()¿Í write()¸¦ ÅëÇØ ÀÔÃâ·ÂÀ» ¼öÇàÇÑ´Ù. ¨ê ÀϹÝÀûÀÎ °æ¿ì close()¿¡¼ Á¢¼Ó ÇØÁ¦ ¿äûÀ» ¼¹ö¿¡°Ô º¸³½ ÈÄ ³×Æ®¿öÅ©ÀÇ ÀÔÃâ·ÂÀ» ³¡³½´Ù.
2-1-4. TCP connectionÀÇ »óÅ º¯ÀÌ
2-1-5. TCP ¿¬°á¿¡¼ÀÇ packet ±³È¯
2-2. UDP Åë½Å
2-2-1. Ư¡
- »ç¿ëÀÚ ÇÁ·Î¼¼½º¿¡°Ô ºñ¿¬°á¼º ¼ºñ½º¸¦ Á¦°øÇÑ´Ù. - ½Å·Ú¼º ÀÖ´Â TCP¿Í ´Þ¸® ÇϳªÀÇ µ¥ÀÌÅͱ׷¥ÀÌ ¿øÇÏ´Â ¸ñÀûÁö È£½ºÆ®¿¡ µµ´ÞÇÑ´Ù´Â º¸Àå ÀÌ ¾ø´Ù.
2-2-2. Ŭ¶óÀ̾ðÆ®/¼¹öÀÇ µ¿ÀÛ
¨ç Á¢¼Ó ¼¹ö¿Í Ŭ¶óÀ̾ðÆ®°£ÀÇ Á¢¼ÓÀ» ¿äûÇÏ°í ¹Þ¾ÆµéÀÌ´Â ºÎºÐÀÌ ¾ø´Ù. ¨è ³×Æ®¿öÅ© ÀÔÃâ·ÂÀº sendto()¿Í recvfrom() µÎ°³ÀÇ ½Ã½ºÅÛ ÄÝÀ» ÀÌ¿ëÇØ µ¿ÀÛÇÑ´Ù. ¨é Á¢¼ÓÀÌ ÀÌ·ç¾îÁöÁö ¾ÊÀº »óÅ¿¡¼ µ¥ÀÌÅ͸¦ ÁÖ°í¹Þ´Â´Ù. ¨ê ±¸Á¶Ã¼¸¦ »ç¿ëÇÏ¿© ÇÊ¿äÇÑ Á¤º¸(IP, port number)¸¦ µ¥ÀÌÅÍ¿Í ÇÔ²² º¸³½´Ù.
3. Socket ProgramingÀÇ ±¸¼º¿ä¼Ò
3-1. ¼ÒÄÏ ÀÎÅÍÆäÀ̽º¿¡¼ »ç¿ëÇÏ´Â µ¥ÀÌÅÍ Å¸ÀÔ
3-1-1. struct sockaddr
ÀÌ ±¸Á¶Ã¼´Â ¿©·¯ °¡Áö ÇüÅÂÀÇ ¼ÒÄÏ ÁÖ¼Ò¸¦ ´ã°ÔµÈ´Ù.
struct sockaddr { unsigned short sa_family; /* address family, AF_xxx */ char sa_data[14]; /* 14 bytes of protocol address */ };
- sa_family´Â ÀÌ ÁÖ¼ÒÀÇ ÁÖ¼Ò Æ÷¸Ë¿ë ÄÚµåÀÌ´Ù. ±×°ÍÀº ´ÙÀ½¿¡ ³ª¿À´Â µ¥ÀÌÅÍÀÇ Æ÷¸ËÀ» Áö ½ÃÇÑ´Ù. - char sa_data[14]´Â ½ÇÁ¦ÀûÀÎ ¼ÒÄÏÁÖ¼Ò µ¥ÀÌÅÍÀÌ´Ù. ÀÌ°ÍÀº Æ÷¸Ë¿¡ ÀÇÁ¸ÇÑ´Ù. ±×°ÍÀÇ ±æÀÌ ´Â ¶ÇÇÑ Æ÷¸Ë¿¡ ÀÇÁ¸ÇÏ°í 14º¸´Ù Å©´Ù. sa_dataÀÇ 14¶ó´Â ±æÀÌ´Â ¿ø·¡ º¯ÇÒ ¼ö ÀÖ´Ù. °¢ ÁÖ¼ÒÆ÷¸ËÀº AF_·Î ½ÃÀÛÇÏ´Â ±âÈ£À̸§À¸·Î ½ÃÀ۵ȴÙ. ±×°ÍµéÀº °¢°¢ À̸§ °ø°£¿¡ ´ëÀÀµÇ ´Â 'PF_' ±âÈ£¿¡ ¸ÂÃçÁ® ÀÖ´Ù. AF_FILE - ÀÌ°ÍÀº ÆÄÀÏ À̸§°ø°£¿¡ ¸Â´Â ÁÖ¼ÒÆ÷¸ËÀÌ´Ù. (PF_FILEÀº ÀÌ À̸§°ø°£ÀÇ À̸§ ÀÌ´Ù.) AF_UNIX - ÀÌ°ÍÀº ȣȯ¼ºÀ» À§ÇÑ AF_FILE°ú °°Àº ¸»ÀÌ´Ù. (PF_UNIX´Â PF_FILE°ú µ¿ ÀǾîÀÌ´Ù.) AF_INET - ÀÌ°ÍÀº ÀÎÅÍ³Ý À̸§°ø°£¿¡ ¸Â´Â ÁÖ¼ÒÆ÷¸ËÀÌ´Ù. (PF_INETÀº ÀÌ À̸§°ø°£ÀÇ ÀÌ ¸§ÀÌ´Ù.) AF_UNSPEC - ÀÌ°ÍÀº ƯÁ¤ÇÑ ÁÖ¼ÒÆ÷¸ËÀ» ÁöÁ¤ÇÏÁö ¾Ê´Â´Ù. ±×°ÍÀº "¿¬°áµÈ" µ¥ÀÌÅͱ׷¥ ¼ÒÄÏÀÇ ±âº»(default)¸ñÀûÁö ÁÖ¼Ò¸¦ Áö¿ì´Â °Í °°Àº µå¹® °æ¿ì¿¡¸¸ »ç¿ëµÈ´Ù.
3-2. struct sockaddr_in
sockaddr ±¸Á¶Ã¼¸¦ ´Ù·ç±â À§ÇÑ parallel structure. ("in"Àº ÀÎÅͳÝÀ» ÀǹÌ.)
struct sockaddr_in { short int sin_family; /* Address family */ unsigned short int sin_port; /* Port number */ struct in_addr sin_addr; /* Internet address */ unsigned char sin_zero[8]; /* Same size as struct sockaddr */ };
ÀÌ ±¸Á¶Ã¼´Â °¢°¢ÀÇ Ç×À» ÂüÁ¶ÇϱⰡ Á»´õ ½±´Ù. ÁÖÀÇÇÒ Á¡Àº sin_zero¹è¿Àº sockaddr°ú ±¸Á¶Ã¼ÀÇ Å©±â¸¦ ¸ÂÃß±â À§Çؼ ³Ö¾îÁø °ÍÀ̹ǷΠbzero()³ª memset()ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© ¸ðµÎ 0À¸·Î ä¿öÁ®¾ß ÇÑ´Ù. ¶ÇÇÑ ÀÌ ±¸Á¶Ã¼´Â sockaddrÀÇ Æ÷ÀÎÅ͸¦ ÀÌ¿ëÇÏ¿© ÂüÁ¶µÉ ¼ö ÀÖ°í ±× ¹Ý´ëµµ °¡´ÉÇÏ´Ù´Â °ÍÀÌ´Ù. µû¶ó¼ socket()ÇÔ¼ö°¡ struct sockaddr *¸¦ ¿øÇÏ´õ¶óµµ struct sockaddr_inÀ» »ç¿ëÇÒ ¼ö ÀÖ°í ¹Ù·Î ÂüÁ¶ÇÒ ¼öµµ ÀÖ´Â °ÍÀÌ´Ù. ¶ÇÇÑ sin_family´Â sa_family¿¡ ´ëÀÀµÇ´Â °ÍÀÌ¸ç ¹°·Ð "AF_INET"·Î ÁöÁ¤µÇ¾î¾ß Çϸçsin_port, sin_addrÀº ³×Æ®¿öÅ© ¹ÙÀÌÆ® ¼ø¼·Î µÇ¾î¾ß ÇÏ´Â Á¡ÀÌ Áß¿äÇÑ °ÍÀÌ´Ù.
3-3. struct in_addr
struct in_addr { unsigned long s_addr; };
3-4. htons()ÇÔ¼ö
"Host to Network Short" - shortº¯¼ö¸¦ È£½ºÆ® ¹ÙÀÌÆ® ¼ø¼¿¡¼ ³×Æ®¿öÅ© ¹ÙÀÌÆ® ¼ø¼·Î º¯È¯ÇÏ´Â °æ¿ì ¨ç htonl() - "Host to Network Long" ¨è ntohs() - "Network to Host Short" ¨é ntohl() - "Network to Host Long" ¨ê inet_ntoa() - °ªÀÌ µé¾îÀÖ´Â struct in_add¸¦ ¼ýÀÚ¿Í Á¡À¸·Î Ç¥½ÃÇϱâ À§ÇØ ¾²ÀÌ´Â ÇÔ¼ö
3-5. socket()ÇÔ¼ö
#include <sys/types.h> #include <sys/socket.h>
int socket(int domain, int type, int protocol); domainÀº struct sockaddr_in ¿¡¼Ã³·³ AF_INET·Î ÁöÁ¤ÇÏ¸é µÈ´Ù.
. AF_UNSPEC . AF_UNIX : ÇϳªÀÇ ½Ã½ºÅÛ ³» . AF_INET : ¼·Î ´Ù¸¥ ½Ã½ºÅÛ °£
typeÀº socketÀÇ Çü½ÄÀ» ÁöÁ¤ÇÏ´Â °ÍÀ¸·Î SOCK_STREAMÀ̳ª SOCK_DGRAMÀ¸·Î ÁöÁ¤ÇÏ¸é µÈ´Ù.
. SOCK_STREAM : TCP -> ¿À·ùÁ¦¾î ÇÊ¿ä ¾øÀ½ . SOCK_DGRAM : U¿¡ -> ¿À·ùÁ¦¾î ÇÊ¿ä½Ã application °èÃþ¿¡¼ ó¸®
protocolÀº 0À¸·Î ÁöÁ¤ÇÏ¸é µÈ´Ù. socket()Àº ¹Ù·Î ³ªÁß¿¡ »ç¿ëÇÒ ¼ÒÄÏ ±â¼úÀÚÀÎ Á¤¼ö °ªÀ» µ¹·ÁÁÖ¸ç ¿¡·¯ ½Ã¿¡´Â -1À» µ¹·ÁÁÖ°Ô µÈ´Ù.
3-6. bind()ÇÔ¼ö
ÀÏ´Ü ¼ÒÄÏÀ» ¿°Ô µÇ¸é ÀÌ ¼ÒÄÏÀ» ÇöÀç ½Ã½ºÅÛÀÇ Æ÷Æ®¿¡ ¿¬°á½ÃÄÑ ÁÖ¾î¾ß ÇÑ´Ù. (ÀÌ ÀÛ¾÷Àº º¸Åë listen()ÇÔ¼ö¸¦ ÀÌ¿ëÇؼ ¿ÜºÎÀÇ Á¢¼ÓÀ» ´ë±âÇÒ ¶§ ½ÃÇàµÇ¸ç ÀϹÝÀûÀ¸·Î ¸Óµå°ÔÀÓ »çÀÌÆ®µéÀÌ telnet *.*.*.* 6969·Î Á¢¼ÓÇ϶ó°í ÇÒ ¶§µµ ÀÌ ÀÛ¾÷À» ½ÃÇàÇß´Ù´Â ÀǹÌÀÌ´Ù) ¸¸¾à¿¡ ±×Àú ´Ù¸¥ È£½ºÆ®¿¡ ¿¬°áÇϱ⸸ ÇÒ ¿¹Á¤À̶ó¸é ±×³É connect()¸¦ »ç¿ëÇÏ¿© ¿¬°á¸¸ ÇÏ¸é µÇ°í ÀÌ ÀÛ¾÷Àº ÇÊ¿ä°¡ ¾ø´Ù.
bind() ½Ã½ºÅÛ È£ÃâÀÇ ¼±¾ð
#include <sys/types.h> #include <sys/socket.h>
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
sockfd´Â socket()ÇÔ¼ö¿¡¼ ¾òÀº ¼ÒÄÏ ±â¼úÀÚÀ̸ç my_addrÀº IP ÁÖ¼Ò¿¡ °üÇÑ Á¤º¸(Áï, IP ÁÖ¼Ò¿Í Æ÷Æ®¹øÈ£)¸¦ ´ã°í ÀÖ´Â struct sockaddr¿¡ ´ëÇÑ Æ÷ÀÎÅÍÀÌ°í addrlenÀº ±× ±¸Á¶Ã¼ÀÇ size(sizeof(struct sockaddr))ÀÌ´Ù.
bind()°¡ ¿¡·¯°¡ ³µÀ» ¶§ -1À» µ¹·ÁÁÖ¸ç errno¿¡ ¿¡·¯ÀÇ Äڵ尡 ³²°Ô µÈ´Ù.
bind()¸¦ È£ÃâÇÒ ¶§ ÁÖÀÇÇÒ Á¡ : Àý´ë Á¦ÇѼ± ¾Æ·¡·Î Æ÷Æ®¹øÈ£¸¦ ³»·Á¼´Â ¾È µÈ´Ù. 1024 ¾Æ·¡ÀÇ ¹øÈ£´Â ¸ðµÎ ¿¹¾àµÇ¾î ÀÖ´Ù. ±× À§·Î´Â 65535±îÁö ¿øÇÏ´Â ´ë·Î ¾µ ¼ö°¡ ÀÖ´Ù. (´Ù¸¥ ÇÁ·Î±×·¥ÀÌ ¾²°í ÀÖÁö ¾ÊÀº °æ¿ì¿¡ ÇÑÇؼ)
bind()¸¦ È£ÃâÇÏÁö ¾Ê¾Æµµ µÇ´Â °æ¿ì°¡ ÀÖ´Ù. ¸¸ÀÏ ´Ù¸¥ È£½ºÆ®¿¡ ¿¬°á (connect())ÇÏ°í ÀÚ ÇÏ´Â °æ¿ì¿¡´Â ÀÚ½ÅÀÇ Æ÷Æ®¿¡´Â (ÅÚ³ÝÀÇ °æ¿ìó·³)ÀüÇô ½Å°æ ¾µ ÇÊ¿ä°¡ ¾ø´Ù. ´ÜÁö connect()¸¦ È£ÃâÇϱ⸸ ÇÏ¸é ¾Ë¾Æ¼ bind°¡ µÇ¾î ÀÖ´ÂÁö¸¦ üũÇؼ ºñ¾îÀÖ´Â Æ÷Æ®¿¡ bind¸¦ ÇØÁØ´Ù.
3-7. connect()ÇÔ¼ö
#include <sys/types.h> #include <sys/socket.h>
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
sockfd´Â ¼ÒÄÏ ±â¼úÀÚÀ̸ç serv_addrÀº ¿¬°áÇÏ°íÀÚ ÇÏ´Â ¸ñÀûÁöÀÎ ¼¹öÀÇ ÁÖ¼Ò¿Í Æ÷Æ® ¿¡ °üÇÑ Á¤º¸¸¦ ´ã°í ÀÖ´Â struct sockaddrÀ̸ç addrlenÀº ¾Õ¿¡¼ À̾߱âÇÑ °Í°ú °°ÀÌ ±× ±¸Á¶Ã¼ÀÇ Å©±âÀÌ´Ù.
3-8. listen()ÇÔ¼ö
¿ÜºÎ·ÎºÎÅÍÀÇ Á¢¼ÓÀ» ´ë±âÇؼ Á¢¼ÓÀÌ ¿Ã °æ¿ì ó¸® ½Ã ¸ÕÀú listen()À» ÇØ¾ß µÇ°í ±× ´ÙÀ½¿¡ accept()¸¦ ÇØ¾ß µÈ´Ù.
int listen(int sockfd, int backlog);
sockfd´Â º¸ÅëÀÇ ¼ÒÄÏ ±â¼úÀÚÀ̸ç backlog´Â Á¢¼Ó´ë±â Å¥ÀÇ ÃÖ´ë ¿¬°á °¡´É ¼ýÀÚÀÌ´Ù. ¿ÜºÎ·ÎºÎÅÍÀÇ ¿¬°áÀº ÀÌ ´ë±â Å¥¿¡¼ accept()°¡ È£ÃâµÉ ¶§±îÁö ±â´Ù·Á¾ß ÇÑ´Ù´Â °ÍÀÌ¸ç ¼ýÀÚ´Â ¹Ù·Î ¾ó¸¶³ª ¸¹Àº Á¢¼ÓÀÌ ÀÌ Å¥¿¡ ½×¿©Áú ¼ö Àִ°¡ ÇÏ´Â °ÍÀÌ´Ù. ´ëºÎºÐÀÇ ½Ã½ºÅÛÀº ÀÌ ¼ýÀÚ¸¦ 20Á¤µµ¿¡¼ Á¦ÇÑÇÏ°í ÀÖÀ¸¸ç º¸ÅëÀº 5¿¡¼ 10 »çÀÌ·Î ÁöÁ¤ÇÑ´Ù. listen()µµ ¿¡·¯ÀÇ °æ¿ì -1À» µ¹·ÁÁÖ¸ç errno¸¦ ¼¼ÆÃÇÑ´Ù. ¿©±â¼ listen()º¸´Ù ¾Õ¼¼ bind()¸¦ È£ÃâÇØ¾ß ÇÏ¸ç ¸¸¾à¿¡ bind()°¡ µÇÁö ¾ÊÀ¸¸é ¿ì¸®´Â ·£´ý ÇÏ°Ô ÁöÁ¤µÈ Æ÷Æ®¿¡¼ ¿ÜºÎÀÇ Á¢¼ÓÀ» ±â´Ù·Á¾ß ÇÑ´Ù. (Æ÷Æ®¸¦ ¸ð¸£°í¼´Â Á¢¼ÓÇÒ ¼ö ¾ø´Ù.) µû¶ó¼ ¿ÜºÎÀÇ Á¢¼ÓÀ» ±â´Ù¸®´Â °æ¿ì¶ó¸é ´ÙÀ½ ¼ø¼´ë·Î ÀÛ¾÷ÀÌ ÁøÇàµÇ¾î¾ß ÇÏ´Â °ÍÀÌ´Ù.
socket(); bind(); listen(); /* accept() goes here */
3-9. accept() ÇÔ¼ö
Connect´Â accept()°¡ È£ÃâµÇ±â±îÁö Queue¿¡¼ accept()¸¦ È£ÃâÇÏ¿© ±× ¿¬°áÀ» Áö¼ÓÇ϶ó°í ¸í·ÉÇÒ ¶§±îÁö ´ë±âÇÏ°Ô µÈ´Ù. ±×·¯¸é ÀÌ ÇÔ¼ö´Â ¿À·ÎÁö ÀÌ ¿¬°áÀ» À§ÇÑ ¼ÒÄÏ ÆÄÀÏ ±â¼úÀÚ¸¦ µ¹·ÁÁÖ°Ô µÈ´Ù. Çϳª °ªÀ¸·Î µÎ°³ÀÇ ¼ÒÄÏ ±â¼úÀÚ¸¦ °®°Ô µÇ´Â °ÍÀÌ´Ù. ¿ø·¡ÀÇ °ÍÀº ¾ÆÁ÷µµ ±× Æ÷Æ®¿¡¼ ¿¬°áÀ» listen()ÇÏ°í ÀÖ´Ù. ¶Ç Çϳª´Â »õ·Î ¸¸µé¾îÁ®¼ send()¿Í recv() ÇÒ Áغñ°¡ µÇµµ·Ï ÇÏ´Â °ÍÀÌ´Ù. ¼±¾ðÀº ¾Æ·¡¿Í °°´Ù.
#include <sys/socket.h> int accept(int sockfd, void *addr, int *addrlen);
sockfd´Â listen()ÇÏ°í ÀÖ´Â ¼ÒÄÏ ±â¼úÀÚÀÌ´Ù. addrÀº ·ÎÄà struct sockaddr_inÀÇ Æ÷ÀÎÅÍÀÌ´Ù. ¿©±â¿¡ µé¾î¿Â Á¢¼Ó¿¡ °üÇÑ Á¤º¸°¡ ´ã°ÜÁö°Ô µÇ°í À̸¦ ÀÌ¿ëÇؼ ¾î´À Host¿¡¼ ¾î´À port¸¦ ÀÌ¿ëÇؼ Á¢¼ÓÀÌ µé¾î¿Ô´ÂÁö¸¦ ¾Ë ¼ö ÀÖ°Ô µÈ´Ù.
addrlenÀº ·ÎÄà Á¤¼ö º¯¼öÀ̸ç ÀÌ Á¤¼ö¿¡´Â struct sockaddr_inÀÇ Å©±â°¡ ¹Ì¸® ÁöÁ¤µÇ¾î ÀÖ¾î¾ß ÇÑ´Ù. ÀÌ ¼ýÀÚº¸´Ù ´õ ¸¹Àº ¹ÙÀÌÆ®ÀÇ Á¤º¸°¡ µé¾î¿À¸é accept()´Â ¹Þ¾ÆµéÀÌÁö ¾ÊÀ» °ÍÀ̸ç Àûµ¥ µé¾î¿Â´Ù¸é addrlenÀÇ °ªÀ» ÁÙ¿© ÁÙ °ÍÀÌ´Ù.
accept() ´Â ¿¡·¯°¡ ³µÀ» °æ¿ì¿¡ -1À» µ¹·ÁÁÖ°í errno¸¦ ¼¼ÆÃÇÑ´Ù.
3-10. send(), recv() - data±³È¯
int send(int sockfd, const void *msg, int len, int flags);
sockfd´Â socket()¸¦ ÅëÇؼ ¾ò¾ú°Å³ª accept()¸¦ ÅëÇؼ »õ·Î ±¸ÇÑ, µ¥ÀÌÅ͸¦ º¸³¾ ¼ÒÄÏÀÇ ±â¼úÀÚÀ̸ç, msg´Â º¸³¾ µ¥ÀÌÅ͸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ, lenÀº º¸³¾ µ¥ÀÌÅÍÀÇ ¹ÙÀÌÆ® ¼öÀ̸ç flags´Â ±×³É 0À¸·Î ÇØ¾ß ÇÑ´Ù.
int recv(int sockfd, void *buf, int len, unsigned int flags);
sockfd´Â Àоî¿Ã ¼ÒÄÏÀÇ ±â¼úÀÚÀ̸ç buf´Â Á¤º¸¸¦ ´ãÀ» ¹öÆÛÀÌ´Ù. lenÀº ¹öÆÛÀÇ ÃÖ´ë Å©±âÀÌ´Ù.
4. ÇÁ·Î±×·¥ ¼Ò½º ¼³¸í
4-1. server.c
/* --------------------------------------------------------------------- */ /* server.c */ /* TCP SocketÀ» ÀÌ¿ëÇÑ Åë½Å (±âº»¿¹Á¦) */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* --------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> // ¿©·¯ °¡Áö Á¤ÀÇµÈ ÀÚ·áÇü µéÀ» »ç¿ëÇϱâ À§ÇØ #include <sys/socket.h> // socket°ú °ü·ÃµÈ ±¸Á¶Ã¼¿Í ÀÚ·áÇü µéÀ» »ç¿ëÇϱâ À§ÇØ #include <netdb.h> // socket°ú °ü·ÃµÈ ÇÔ¼ö¿Í ±¸Á¶Ã¼¸¦ »ç¿ëÇϱâ À§ÇØ #include <netinet/in.h> // socketaddr_in ±¸Á¶Ã¼¸¦ »ç¿ëÇϱâ À§ÇØ #include <arpa/inet.h> // ALPA internet protocol°ú °ü·Ã µÈ ±¸Á¶Ã¼¸¦ »ç¿ëÇϱâ À§ÇØ
#define ServicePort 8001 #define MSG "Server processed successfully according your requests."
int main() { int pid, num; int Rsock, Csock; // Socket Descriptor char ServerName[20]; // Server Domain Name int ClientAddrLen; // Client Address Length char buf[80]; // Receiving Buffer struct sockaddr_in SockAddr; struct sockaddr_in ClientAddr; /*Updated for Client Addr Info : struct sockaddr ClientAddr */ if (gethostname(ServerName, sizeof(ServerName))) { printf("Server Error! gethostname() error\n"); exit(-1); }
// server name display printf("\n[Server] server name: %s\n", ServerName);
// rendezvous socket create if ((Rsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Server Error! socket() error"); exit(-1); } // socket create display printf("[Server] Socket created.\n");
// socket struct ÃʱâÈ bzero((char*) &SockAddr, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr.sin_port = htons(ServicePort);
// rendezvous socket bind if (bind(Rsock, (struct sockaddr *) &SockAddr, sizeof(SockAddr))) { printf("Server Error! bind() error"); exit(-1); } // bind display printf("[Server] Socket binded.\n");
// listen if (listen(Rsock, 5)) { printf("Server Error! listen() error"); exit(-1); } // listened display printf("[Server] Socket listened.\n");
while (1) { // Waiting for connection request. printf("[Server] Waiting for connection request.\n\n"); ClientAddrLen = sizeof(ClientAddr);
// accept if ((Csock = accept(Rsock, (struct sockaddr *) &ClientAddr, &ClientAddrLen)) < 0) { printf("Server Error! accept() error\n"); printf("Rsock = %d Csock = %d\n", Rsock, Csock); exit(-1); } // client IP¿Í ÇÔ²² Á¢¼ÓÀÌ µÇ¾ú´Ù´Â ¸Þ½ÃÁö¸¦ ȸ鿡 Ç¥½Ã printf("[Server] Client(%s) and Server Connected.\n", inet_ntoa(ClientAddr.sin_addr)); // child process¸¦ »ý¼ºÇÏ°Ú´Ù´Â ¸Þ½ÃÁö Ç¥½Ã printf("[Server] Create child process.\n");
// process fork if ((pid = fork()) < 0 ) { printf("Server Error! fork() error"); exit(-1); } else if (pid == 0) { /* Child Process */ close(Rsock); // process fork ÈÄ client·ÎºÎÅÍ µ¥ÀÌÅÍ°¡ ¿À±æ ±â´Ù¸² printf("[Child] Waiting for client data.\n"); if ((num = recv(Csock, buf, sizeof(buf), 0)) < 0) { printf("[Child] Receive Error!\n"); exit(-1); } // client IP¿Í Port ±×¸®°í µ¥ÀÌÅ͸¦ ȸ鿡 Ç¥½Ã printf("[Child] Data from Client(%s:%d) [%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf); // Àß ¹Þ¾Ò´Ù´Â ¸Þ½ÃÁö Send send(Csock, MSG, (sizeof(MSG)), 0); printf("[Child] Sent response message to client.\n"); printf("[Child] Exit.\n"); close(Csock); // Be Careful! exit(0); } else if (pid > 0) { /* Parent Process */ close(Csock); } } }
4-2. client.c
/* --------------------------------------------------------------------- */ /* client.c */ /* TCP SocketÀ» ÀÌ¿ëÇÑ Åë½Å (±âº»¿¹Á¦) */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* --------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <string.h>
#define MAXSIZE 512 #define ServicePort 8001
int main(int argc, char *argv[]) { int sd; struct in_addr *InetAddr; struct sockaddr_in ServerSockAddr; struct hostent *ServerInfo; char SndBuf[MAXSIZE], RcvBuf[MAXSIZE];
// serverÀÇ À̸§À¸·Î IP address¸¦ ¾ò´Â´Ù. if ((ServerInfo = gethostbyname(argv[1])) == NULL) { printf("Client Error! gethostbyname() error\n"); exit(-1); } InetAddr = (struct in_addr *) *(ServerInfo->h_addr_list); //Server address display printf("[Client] sever address %s \n", inet_ntoa(*InetAddr)); if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { printf("Client Error! socket() error \n"); exit(-1); } // socket create display printf("[Client] Socket created.\n");
// socket struct ÃʱâÈ bzero((char*) &ServerSockAddr, sizeof(ServerSockAddr)); ServerSockAddr.sin_family = AF_INET; ServerSockAddr.sin_addr.s_addr = InetAddr->s_addr; ServerSockAddr.sin_port = htons(ServicePort);
printf("[Client] Clint send connection request.\n"); if (connect(sd, (struct sockaddr *) &ServerSockAddr, sizeof(ServerSockAddr)) < 0) { printf("Client Error! connect() error\n"); exit(-1); } // connect display printf("[Client] Clint and server connected.\n");
printf("[Client] Input Data ? "); gets(SndBuf);
send(sd, SndBuf, (sizeof(SndBuf)), 0); printf("[Client] Client sent Data.\n");
recv(sd, RcvBuf, (sizeof(RcvBuf)), 0); printf("[Client] Client received Data.\n");
printf("[Client] Data from Server [%s]\n", RcvBuf); close(sd); printf("[Client] Client Exit.\n"); }
5. ½ÇÇà ȯ°æ
5-1. »ç¿ë machine
- SunOS 5.7 - WOW Linux 7.0 - ALZZA Linux 6.1
5-2. »ç¿ë °èÁ¤
- Server address : seed.ks.ac.kr - User ID : XXXXXXXX - Password : XXXXXXXX
6. CASE ¿¬±¸
6-1. °¢ clientÀÇ ¿äûÀ» µ¶¸³ÀûÀÎ child process°¡ client¿Í Á¢¼ÓÇÏ¿© Åë½ÅÇÏ´Â concurrent ¼ºñ½º ¹æ½Ä¿¡ ÀÇÇØ Åë½ÅÇÏ´Â °æ¿ì ?
¨ç µ¿ÀÛ È¯°æ(source code) rendezvous socketÀ» forkÇÏ¿© ¸¸µç communication socketÀÌ client process¿Í Åë½ÅÇÏ°Ô ¸¸µç´Ù. ¶ÇÇÑ ¿©·¯ client°¡ Á¢¼ÓÇÑ´Ù´Â °¡Á¤¿¡ ÀÇÇØ client¿¡¼´Â ³Ñ°ÜÁÙ µ¥ÀÌÅ͸¦ ¸ÕÀú ¹Þ°í connect¸¦ ÇÑ´Ù. server.c´Â ±âº»¿¹Á¦¿Í °°°í client.c¿¡¼ µ¥ÀÌÅ͸¦ ÀԷ¹޴ ºÎºÐ¸¸ ¾Æ·¡¿Í °°ÀÌ ¼Ò½º¸¦ ¼öÁ¤ÇÑ´Ù. Service Port´Â 8002¹øÀÌ´Ù.
/* --------------------------------------------------------------------- */ /* client.c */ /* Case 6-1) : TCP SocketÀ» ÀÌ¿ëÇÑ Åë½Å (Concurrent Service) */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* --------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <string.h> #define MAXSIZE 512 #define ServicePort 8002
int main(int argc, char *argv[]) { int sd; struct in_addr *InetAddr; struct sockaddr_in ServerSockAddr; struct hostent *ServerInfo; char SndBuf[MAXSIZE], RcvBuf[MAXSIZE];
printf("[Client] Input Data ? "); // Updated! for checking concurrent service gets(SndBuf);
if ((ServerInfo = gethostbyname(argv[1])) == NULL) { printf("Client Error! gethostbyname() error\n"); exit(-1); } InetAddr = (struct in_addr *) *(ServerInfo->h_addr_list); printf("[Client] sever address %s \n", inet_ntoa(*InetAddr));
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { printf("Client Error! socket() error \n"); exit(-1); } printf("[Client] Socket created.\n");
bzero((char*) &ServerSockAddr, sizeof(ServerSockAddr)); ServerSockAddr.sin_family = AF_INET; ServerSockAddr.sin_addr.s_addr = InetAddr->s_addr; ServerSockAddr.sin_port = htons(ServicePort);
printf("[Client] Clint sent connection request.\n"); if (connect(sd, (struct sockaddr *) &ServerSockAddr, sizeof(ServerSockAddr)) < 0) { printf("Client Error! connect() error\n"); exit(-1); } printf("[Client] Clint and server connected.\n"); // printf("[Client] Input Data ? "); // gets(SndBuf);
send(sd, SndBuf, (sizeof(SndBuf)), 0); printf("[Client] Client sent Data.\n");
recv(sd, RcvBuf, (sizeof(RcvBuf)), 0); printf("[Client] Client received Data.\n");
printf("[Client] Data from Server [%s]\n", RcvBuf); close(sd); printf("[Client] Client Exit.\n"); } ¨è ½ÇÇà °á°ú
server¸¦ ½ÇÇà½ÃÅ°°í connection request¸¦ ±â´Ù¸®°í ÀÖ´Ù.
netatat : server¸¦ ½ÇÇà½ÃÅ°°í ³×Æ®Œö »óŸ¦ È®ÀÎ
client : client 3°³¸¦ µ¿½Ã¿¡ ¿¾î µ¥ÀÌÅ͸¦ Àü´ÞÇÑ´Ù. ù ¹ø°´Â 11111111À», µÎ ¹ø°´Â 2222222222, ¼¼ ¹ø°´Â 33333333333À» µ¿½Ã¿¡ º¸³Â´Ù.
server : 3°³ÀÇ client·ÎºÎÅÍ µ¥ÀÌÅ͸¦ Àü´Þ¹Þ¾Ò´Ù.
netstat : µ¥ÀÌÅ͸¦ ¸ðµÎ Àü´Þ¹ÞÀº ÈÄÀÇ ³×Æ®Œö »óÅÂÀÌ´Ù.
¨é °á°ú ºÐ¼® Client°¡ connectÈÄ ¼¼ ¹ø fork°úÁ¤À» °Åó ¼¼ °³ÀÇ process°¡ °¢°¢ data¸¦ Àü´ÞÇÏ´Â °úÁ¤À» È®ÀÎ ÇÒ ¼ö ÀÖ´Ù. ½ÇÁúÀûÀ¸·Î ¾ÆÁÖ Á¤È®ÇÑ Å×½ºÆ®´Â µÇÁö ¸øÇß´Ù. µ¥ÀÌÅ͸¦ º¸³»´Â ±× ¼ø°£ ¼¼ °³ÀÇ process°¡ »ý¼ºµÇ¾î µ¿½Ã¿¡ 󸮵Ǿî¾ß Çϴµ¥, À§ÀÇ °æ¿ì´Â ÇϳªÀÇ µ¥ÀÌÅ͸¦ ¹Þ°í process°¡ Á¾·á ÈÄ ¶Ç ÇϳªÀÇ µ¥ÀÌÅ͸¦ ¹Þ´Â Çü½ÄÀ¸·Î ¼øÂ÷ÀûÀ¸·Î ÀÌ·ç¾îÁø´Ù.
6-2. °¢ clientÀÇ ¿äûÀ» parent process°¡ Çѹø¿¡ Çϳª¾¿ Åë½ÅÇÏ´Â interative ¼ºñ½º ¹æ ½Ä¿¡ ÀÇÇØ child process°¡ client¿Í Åë½ÅÇÏ´Â °æ¿ì ?
¨ç µ¿ÀÛ È¯°æ(source code) rendezvous socketÀ» forkÇÏÁö ¾Ê°í client process¿Í Á÷Á¢ Åë½ÅÇÏ°Ô ¸¸µç´Ù. server.c´Â forkÇÏ´Â ºÎºÐÀ» ÁÖ¼®Ã³¸® ÇÏ¿© ¾Æ·¡¿Í °°°í, client.c´Â ±âº»¿¹Á¦¿Í µ¿ÀÏÇÏ´Ù. Service Port´Â 8002¹øÀÌ´Ù.
/* --------------------------------------------------------------------- */ /* server.c */ /* Case 6-2) : TCP SocketÀ» ÀÌ¿ëÇÑ Åë½Å (Iterative Service) */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* --------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h>
#define ServicePort 8002 #define MSG "Server processed successfully according your requests."
int main() { int pid, num; int Rsock, Csock; // Socket Descriptor char ServerName[20]; // Server Domain Name int ClientAddrLen; // Client Address Length char buf[80]; // Receiving Buffer struct sockaddr_in SockAddr; struct sockaddr_in ClientAddr; // struct sockaddr ClientAddr;
if (gethostname(ServerName, sizeof(ServerName))) { printf("Server Error! gethostname() error\n"); exit(-1); } printf("\n[Server] server name: %s\n", ServerName);
if ((Rsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Server Error! socket() error"); exit(-1); } printf("[Server] Socket created.\n");
bzero((char*) &SockAddr, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr.sin_port = htons(ServicePort);
if (bind(Rsock, (struct sockaddr *) &SockAddr, sizeof(SockAddr))) { printf("Server Error! bind() error"); exit(-1); } printf("[Server] Socket binded.\n");
if (listen(Rsock, 5)) { printf("Server Error! listen() error"); exit(-1); } printf("[Server] Socket listened.\n");
while (1) { printf("[Server] Waiting for connection request.\n\n");
ClientAddrLen = sizeof(ClientAddr); if ((Csock = accept(Rsock, (struct sockaddr *) &ClientAddr, &ClientAddrLen))< 0) { printf("Server Error! accept() error\n"); printf("Rsock = %d Csock = %d\n", Rsock, Csock); exit(-1); } printf("[Server] Client(%s) and Server Connected.\n", inet_ntoa(ClientAddr.sin_addr)); /* printf("[Server] Created child process.\n");
if ((pid = fork()) < 0 ) { printf("Server Error! fork() error"); exit(-1); } else if (pid == 0) { //* Child Process close(Rsock); */ printf("[Child] Waiting for client data.\n");
if ((num = recv(Csock, buf, sizeof(buf), 0)) < 0) { printf("[Child] Receive Error!\n"); exit(-1); }
printf("[Child] Data from Client(%s:%d) [%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf); send(Csock, MSG, (sizeof(MSG)), 0); printf("[Child] Sent response message to client.\n"); /* printf("[Child] Exit.\n"); close(Csock); // Be Careful! exit(0); } else if (pid > 0) { // Parent Process */ close(Csock); /* } */ } }
¨è ½ÇÇà °á°ú
server : server.c¸¦ ½ÇÇà½ÃÅ°°í 3°³ÀÇ client·ÎºÎÅÍ µ¥ÀÌÅ͸¦ Àü´Þ¹ÞÀ» °ÍÀÌ´Ù.
client : 3°³ÀÇ client°¡ server·Î Á¢¼ÓÀ» Çؼ °¢ data¸¦ Àü´ÞÇϱ⠹ٷΠÀü ȸéÀÌ´Ù. °¡Àå ¸ÕÀú Á¢¼ÓÇÑ client°¡ 11111111111111À̶õ data¸¦ µÎ ¹ø° Á¢¼ÓÇÑ client°¡ 22222222222222¶ó´Â data¸¦ ¼¼ ¹ø° Á¢¼ÓÇÑ client°¡ 333333333333333À̶ó´Â µ¥ÀÌÅ͸¦ ÀÔ·Â¹Þ¾Æ º¸³»´Âµ¥ Á¦ÀÏ ¸¶Áö¸·¿¡ Á¢¼ÓÇÑ ¼¼ ¹ø° clientºÎÅÍ µ¥ÀÌÅ͸¦ º¸³¾ °ÍÀÌ´Ù.
netstat : 3°³ÀÇ client°¡ °¢ °¢ Â÷·Ê´ë·Î Á¢¼ÓÀ» ÇÏ°í µ¥ÀÌÅÍ´Â º¸³»Áö ¾Ê¾Ò´Ù. listen ´ë±â queue¿¡ ³ª¸ÓÁö µÎ °³ÀÇ client°¡ µé¾î ÀÖÀ½À» ¾Ë ¼ö ÀÖ´Ù.
server : 3°³ÀÇ client·ÎºÎÅÍ Á¢¼ÓÇÑ ¼ø¼ ¹Ý´ë·Î data¸¦ Àü´Þ¹Þ¾ÒÀ¸³ª Á¢¼ÓÇÑ ¼ø¼´ë·Î data °¡ µµÂøÇÑ °ÍÀ» º¼ ¼ö ÀÖ´Ù.
¨é °á°ú ºÐ¼® child process¸¦ ¸¸µéÁö ¾Ê°í parent process°¡ ¸ðµç client¿Í Á÷Á¢ Åë½ÅÀ» ÇÏ¿´´Ù. Á¢¼ÓÇÑ ¼ø¼ÀÇ ¹Ý´ë·Î data¸¦ º¸³Â´Âµ¥ server¿¡¼´Â Á¢¼ÓÇÑ ¼ø¼´ë·Î data°¡ µµÂøÇßÀ½À» º¼ ¼ö ÀÖ´Ù. ÀÌ´Â ¸ÕÀú Á¢¼ÓÇÑ client°¡ server·ÎºÎÅÍ service¸¦ ¹Þ¾ÒÀ½À» ¾Ë ¼ö ÀÖ´Ù.
6-3. Bind ÇÔ¼öÀÇ ±â´É (TCP Socket)
1) Server´Â ¹Ýµå½Ã PortÀÇ BindingÀÌ ÇÊ¿äÇÑ°¡ (server¿¡ bind ÇÏÁö ¾ÊÀ» °æ¿ì) ?
¨ç µ¿ÀÛ È¯°æ client.c´Â ±âº» ¿¹Á¦ ±×´ë·Î ÀÌ°í server.c´Â ¾Æ·¡¿Í °°ÀÌ bind ºÎºÐ¸¸ ÁÖ¼® ó¸®ÇÏ¸é µÈ´Ù. service port´Â 8004¹øÀÌ´Ù.
/* --------------------------------------------------------------------- */ /* server.c */ /* Case 6-3) : Port Binding ¹®Á¦ (TCP Socket) */ /* 1) Server´Â ¹Ýµå½Ã PortÀÇ BindingÀÌ ÇÊ¿äÇÑ°¡? */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* --------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h>
#define ServicePort 8004 #define MSG "Server processed successfully according your requests."
int main() { int pid, num; int Rsock, Csock; char ServerName[20]; int ClientAddrLen; char buf[80]; struct sockaddr_in SockAddr; struct sockaddr_in ClientAddr;
if (gethostname(ServerName, sizeof(ServerName))) { printf("Server Error! gethostname() error\n"); exit(-1); } printf("\n[Server] server name: %s\n", ServerName); if ((Rsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Server Error! socket() error"); exit(-1); } printf("[Server] Socket created.\n"); bzero((char*) &SockAddr, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr.sin_port = htons(ServicePort); /* if (bind(Rsock, (struct sockaddr *) &SockAddr, sizeof(SockAddr))) { printf("Server Error! bind() error"); exit(-1); } printf("[Server] Socket binded.\n"); */ if (listen(Rsock, 5)) { printf("Server Error! listen() error"); exit(-1); } printf("[Server] Socket listened.\n"); while (1) { printf("[Server] Waiting for connection request.\n\n"); ClientAddrLen = sizeof(ClientAddr); if ((Csock = accept(Rsock, (struct sockaddr *) &ClientAddr, &ClientAddrLen)) < 0) { printf("Server Error! accept() error\n"); printf("Rsock = %d Csock = %d\n", Rsock, Csock); exit(-1); } printf("[Server] Client(%s) and Server Connected.\n", inet_ntoa(ClientAddr.sin_addr)); printf("[Server] Created child process.\n"); if ((pid = fork()) < 0 ) { printf("Server Error! fork() error"); exit(-1); } else if (pid == 0) { /* Child Process */ close(Rsock); printf("[Child] Waiting for client data.\n"); if ((num = recv(Csock, buf, sizeof(buf), 0)) < 0) { printf("[Child] Receive Error!\n"); exit(-1); } printf("[Child] Data from Client(%s:%d) [%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf); send(Csock, MSG, (sizeof(MSG)), 0); printf("[Child] Sent response message to client.\n"); printf("[Child] Exit.\n"); close(Csock); // Be Careful! exit(0); } else if (pid > 0) { /* Parent Process */ close(Csock); } } }
¨è ½ÇÇà °á°ú
server : Á¤»óÀûÀÎ ÄÄÆÄÀÏ°ú ½ÇÇàÀÌ µÈ´Ù.
client : ½ÇÇà ½Ã connect error°¡ ¹ß»ýÇÑ´Ù.
¨é °á°ú ºÐ¼® Server´Â ²À bind¸¦ ÇØ¾ß ÇÑ´Ù. server ÇÁ·Î±×·¥À» ½ÇÇà ½Ã¿¡´Â ¾Æ¹«·± ¹®Á¦°¡ ¾øÀ¸³ª client ÇÁ·Î±×·¥ÀÌ server·Î Á¢¼Ó ½ÃÁ¡¿¡ connect¿¡·¯°¡ ³´Ù.
2) Client°¡ Port¸¦ BindingÇÏ¸é ¾î¶°ÇÑ°¡?
¨ç µ¿ÀÛ È¯°æ serverÇÁ·Î±×·¥Àº ±âº»¿¹Á¦¿Í °°°í, clientÇÁ·Î±×·¥¿¡¼´Â sockaddr_in ±¸Á¶Ã¼¸¦ ´Ù½Ã Çϳª ¼±¾ðÇÏ°í ±¸Á¶Ã¼¸¦ ÃʱâÈ ÇÑ ÈÄ bindÇÏ¸é µÇ°í ÇÁ·Î±×·¥ ¼öÁ¤ ºÎºÐÀº ¾Æ·¡¿Í °°´Ù. serverÀÇ service port´Â 8005, clientÀÇ service port´Â 9000ÀÌ´Ù.
/* -------------------------------------------------------------------- */ /* client.c */ /* Case 6-3) : Port Binding ¹®Á¦ (TCP Socket) */ /* 2) Client°¡ Port¸¦ BindingÇÏ¸é ¾î¶°ÇÑ°¡? */ /* client´Â 9000¹ø port·Î bindÇÑ´Ù. */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* ------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <string.h>
#define MAXSIZE 512 #define ServicePort 8005
int main(int argc, char *argv[]) { int sd; struct in_addr *InetAddr; struct sockaddr_in ServerSockAddr; struct sockaddr_in ClientSockAddr; // Updated! Inserted for Port Binding struct hostent *ServerInfo; char SndBuf[MAXSIZE], RcvBuf[MAXSIZE];
if ((ServerInfo = gethostbyname(argv[1])) == NULL) { printf("Client Error! gethostbyname() error\n"); exit(-1); } InetAddr = (struct in_addr *) *(ServerInfo->h_addr_list); printf("[Client] sever address %s \n", inet_ntoa(*InetAddr));
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { printf("Client Error! socket() error \n"); exit(-1); } printf("[Client] Socket created.\n");
bzero((char*) &ServerSockAddr, sizeof(ServerSockAddr)); ServerSockAddr.sin_family = AF_INET; ServerSockAddr.sin_addr.s_addr = InetAddr->s_addr; ServerSockAddr.sin_port = htons(ServicePort);
// Updated! Inserted for Port Client's Port Binding bzero((char*) &ClientSockAddr, sizeof(ClientSockAddr)); ClientSockAddr.sin_family = AF_INET; ClientSockAddr.sin_addr.s_addr = htonl(INADDR_ANY); ClientSockAddr.sin_port = htons(9000);
if (bind(sd, (struct sockaddr *) &ClientSockAddr, sizeof(ClientSockAddr))) { printf("Client Error! bind() error"); exit(-1); } printf("[Client] Socket binded.\n"); // End of Insertion
printf("[Client] Clint sent connection request.\n"); if (connect(sd, (struct sockaddr *) &ServerSockAddr, sizeof(ServerSockAddr)) < 0) { printf("Client Error! connect() error\n"); exit(-1); } printf("[Client] Clint and server connected.\n");
printf("[Client] Input Data ? "); gets(SndBuf);
send(sd, SndBuf, (sizeof(SndBuf)), 0); printf("[Client] Client sent Data.\n");
recv(sd, RcvBuf, (sizeof(RcvBuf)), 0); printf("[Client] Client received Data.\n");
printf("[Client] Data from Server [%s]\n", RcvBuf);
close(sd); printf("[Client] Client Exit.\n"); }
¨è ½ÇÇà °á°ú
server : server¸¦ ½ÇÇàÇÑ È¸é
netstat : server°¡ 8005¹ø port·Î listen»óÅÂÀÓÀ» ¾Ë ¼ö ÀÖ´Ù.
client : client¸¦ ½ÇÇàÇϸé 9000 port·Î bindÇÒ °ÍÀÌ´Ù.
netstat : client°¡ Á¢¼Ó ÈÄ ³×Æ®Œö »óŸ¦ º¸¸é server´Â 8005¿¡ bind µÇ¾ú°í, client´Â 9000 ¹ø¿¡ bindµÈ °ÍÀ» È®ÀÎ ÇÒ ¼ö ÀÖ´Ù.
¨é °á°ú ºÐ¼® server´Â ²À bind¸¦ ÇØ¾ß µÈ´Ù. ÇÏÁö¸¸ client´Â bind¸¦ Çصµ »ó°üÀÌ ¾ø°í ÇÏÁö ¾Ê¾Æµµ »ó°üÀÌ ¾ø´Ù. ÇÏÁö¸¸ client°¡ bind¸¦ ÇÏÁö ¾Ê´Â °ÍÀ» ¿øÄ¢À¸·Î ÇÏ´Â °ÍÀº ´ÙÀ½°ú °°Àº ÀÌÀ¯ÀÌ´Ù. client°¡ bind¸¦ ÇÏÁö ¾ÊÀ¸¸é ÀÚ½ÅÀÇ port´Â ´Ù¸¥ Åë½Å·Î¿Í Áߺ¹µÇÁö ¾Ê´Â port¸¦ ÇÒ´çÇؼ Åë½ÅÀ» ÇÑ´Ù. ±×·¯³ª ÀÓÀÇÀÇ Æ÷Æ®°¡ ¾Æ´Ñ ÇϳªÀÇ Æ¯Á¤ port¸¦ bindÇÏ°Ô µÇ¸é ±× Æ÷Æ®·Î ÇϳªÀÇ client´Â Á¢¼ÓÀÌ µÈ´Ù. ÇÏÁö¸¸ ¶Ç ´Ù¸¥ client¿¡¼ °°Àº port·Î Åë½ÅÀ» ½ÃµµÇÏ°Ô µÇ¸é bind error°¡ ³ª±â ¶§¹®ÀÌ´Ù.
6-4. Listen ÇÔ¼öÀÇ ±â´É (TCP Socket)
1) Server°¡ listen()À» ºüÆ®¸° °æ¿ì ¾î¶»°Ô µÇ³ª ?
¨ç µ¿ÀÛ È¯°æ server.c´Â listen ºÎºÐÀ» ¾Æ·¡¿Í °°ÀÌ ÁÖ¼® ó¸®ÇÏ¿´°í, client.c´Â ±âº»¿¹Á¦ ±×´ë·ÎÀÌ´Ù. service port´Â 9000¹øÀÌ´Ù.
/* --------------------------------------------------------------------- */ /* server.c */ /* Case 6-4 : Listen ÇÔ¼öÀÇ ±â´É (TCP Socket) */ /* 1) Server°¡ listen()À» ºüÆ®¸° °æ¿ì ¾î¶»°Ô µÇ³ª ? */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* -------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h> #define ServicePort 9000 #define MSG "Server processed successfully according your requests."
int main() { int pid, num; int Rsock, Csock; // Socket Descriptor char ServerName[20]; // Server Domain Name int ClientAddrLen; // Client Address Length char buf[80]; // Receiving Buffer struct sockaddr_in SockAddr; struct sockaddr_in ClientAddr; // struct sockaddr ClientAddr;
if (gethostname(ServerName, sizeof(ServerName))) { printf("Server Error! gethostname() error\n"); exit(-1); } printf("\n[Server] server name: %s\n", ServerName); if ((Rsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Server Error! socket() error"); exit(-1); } printf("[Server] Socket created.\n");
bzero((char*) &SockAddr, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr.sin_port = htons(ServicePort);
if (bind(Rsock, (struct sockaddr *) &SockAddr, sizeof(SockAddr))) { printf("Server Error! bind() error"); exit(-1); } printf("[Server] Socket binded.\n");
/* Updated! Deleted for checking listen() if (listen(Rsock, 5)) { printf("Server Error! listen() error"); exit(-1); } printf("[Server] Socket listened.\n"); */ while (1) { printf("[Server] Waiting for connection request.\n\n");
ClientAddrLen = sizeof(ClientAddr); if ((Csock = accept(Rsock, (struct sockaddr *) &ClientAddr, &ClientAddrLen)) < 0) { printf("Server Error! accept() error\n"); printf("Rsock = %d Csock = %d\n", Rsock, Csock); exit(-1); } printf("[Server] Client(%s) and Server Connected.\n", inet_ntoa(ClientAddr.sin_addr)); printf("[Server] Created child process.\n"); if ((pid = fork()) < 0 ) { printf("Server Error! fork() error"); exit(-1); } else if (pid == 0) { /* Child Process */ close(Rsock); printf("[Child] Waiting for client data.\n"); if ((num = recv(Csock, buf, sizeof(buf), 0)) < 0) { printf("[Child] Receive Error!\n"); exit(-1); } printf("[Child] Data from Client(%s:%d) [%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf); send(Csock, MSG, (sizeof(MSG)), 0); printf("[Child] Sent response message to client.\n"); printf("[Child] Exit.\n"); close(Csock); // Be Careful! exit(0); } else if (pid > 0) { /* Parent Process */ close(Csock); } } }
¨è ½ÇÇà °á°ú
server : runtime½Ã accept error°¡ ¹ß»ýÇÑ´Ù.
¨é °á°ú ºÐ¼® BSD Socket¿¡¼´Â listenÀº client¿Í connect¸¦ Çϱâ À§ÇØ ²À ÇÊ¿äÇÏ´Ù.
2) listen() ÇÔ¼ö·Î QueueÀÇ Å©±â¸¦ 1·Î ÁöÁ¤Çϸé ?
¨ç µ¿ÀÛ È¯°æ. listenÀº server¿¡ µ¿½Ã ¿¬°á µÉ ¼ö ÀÖ´Â clientÀÇ ¼ö¸¦ ÁöÁ¤ÇÑ´Ù. listen ÇÔ¼öÀÇ ÀÎÀÚ °ªÀ» 1·Î ÁöÁ¤Çؼ ÇÁ·Î±×·¥À» ½ÇÇà½ÃÅ°¸é È®ÀÎ ÇÒ ¼ö ÀÖ´Ù. ¹«ÇÑ ·çÇÁ¸¦ µ¹±â Àü¿¡(client¿Í Á¢¼ÓÀÌ ÀÌ·ç¾îÁö±â Àü) ÀÓÀÇÀÇ ¼ýÀÚ¸¦ ÀԷ¹޵µ·Ï ÇÏ¿´´Ù. server.c´Â ¾Æ·¡¿Í °°ÀÌ ¼Ò½º ¼öÁ¤À» ÇÏ¸é µÇ°í, client.c´Â ±âº» ¿¹Á¦ÀÌ´Ù. service port´Â 9001ÀÌ´Ù.
/* -------------------------------------------------------------------- */ /* server.c */ /* Case 6-4) : Listen ÇÔ¼öÀÇ ±â´É (TCP Socket) */ /* 2) listen() ÇÔ¼ö·Î QueueÀÇ Å©±â¸¦ 1·Î ÁöÁ¤Çϸé ? */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* ------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h>
#define ServicePort 9001 #define MSG "Server processed successfully according your requests."
int main() { int pid, num; int Rsock, Csock; // Socket Descriptor char ServerName[20]; // Server Domain Name int ClientAddrLen; // Client Address Length char buf[80]; // Receiving Buffer struct sockaddr_in SockAddr; struct sockaddr_in ClientAddr; // struct sockaddr ClientAddr; if (gethostname(ServerName, sizeof(ServerName))) { printf("Server Error! gethostname() error\n"); exit(-1); } printf("\n[Server] server name: %s\n", ServerName);
if ((Rsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Server Error! socket() error"); exit(-1); } printf("[Server] Socket created.\n");
bzero((char*) &SockAddr, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr.sin_port = htons(ServicePort);
if (bind(Rsock, (struct sockaddr *) &SockAddr, sizeof(SockAddr))) { printf("Server Error! bind() error"); exit(-1); } printf("[Server] Socket binded.\n");
if (listen(Rsock, 1)) { // Updated! Queue size = 0 || 1 printf("Server Error! listen() error"); exit(-1); } printf("[Server] Socket listened.\n");
printf("If continue, enter any number. "); scanf("%d", &num);// Updated
while (1) { printf("[Server] Waiting for connection request.\n\n"); ClientAddrLen = sizeof(ClientAddr); if ((Csock = accept(Rsock, (struct sockaddr *) &ClientAddr, &ClientAddrLen)) < 0) { printf("Server Error! accept() error\n"); printf("Rsock = %d Csock = %d\n", Rsock, Csock); exit(-1); } printf("[Server] Client(%s) and Server Connected.\n", inet_ntoa(ClientAddr.sin_addr)); printf("[Server] Created child process.\n");
if ((pid = fork()) < 0 ) { printf("Server Error! fork() error"); exit(-1); } else if (pid == 0) { /* Child Process */ close(Rsock); printf("[Child] Waiting for client data.\n"); if ((num = recv(Csock, buf, sizeof(buf), 0)) < 0) { printf("[Child] Receive Error!\n"); exit(-1); }
printf("[Child] Data from Client(%s:%d) [%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf);
send(Csock, MSG, (sizeof(MSG)), 0); printf("[Child] Sent response message to client.\n");
printf("[Child] Exit.\n"); close(Csock); // Be Careful! exit(0); } else if (pid > 0) { /* Parent Process */ close(Csock); } } }
¨è ½ÇÇà °á°ú
server : accept¸¦ Çϱâ Àü µ¿½Ã¿¡ 3°³ÀÇ clientÀÇ Á¢¼ÓÀ» ¹Þ±â À§ÇØ ´ë±â ÁßÀÌ´Ù.
client 1,2 : µÎ °³ÀÇ client´Â À§¿Í °°Àº ȸéó·³ Á¢¼ÓÀÌ ÀÌ·ç¾î Á³´Ù.
client 3 : ¼¼ ¹ø° client´Â À§¿Í °°Àº ȸéó·³ Á¢¼Ó ¿äûÀ» º¸³ÂÁö¸¸ Á¢¼ÓÀÌ µÇÁö ¾Ê¾Ò´Ù.
server : client 1,2¿¡¼ data¸¦ º¸³»ÀÚ data¸¦ Àü´Þ¹Þ¾Ò´Ù.
server : client 1, 2ÀÇ data¸¦ Àü´Þ¹Þ°í 10ÃÊ Á¤µµ ½Ã°£ÀÌ Áö³ªÀÚ 3¹ø° clientµµ Á¢¼ÓÀÌ ÀÌ ·ç¾î Á³´Ù.
client 3 : client 1, 2°¡ server·Î data¸¦ Àü´Þ ÈÄ ¾à 10ÃÊ µÚ client 3ÀÌ server¿Í connectµÇ ¾ú´Ù.
¨é °á°ú ºÐ¼® listen ÇÔ¼ö´Â server¿¡ µ¿½Ã¿¡ Á¢¼ÓµÉ ¼ö ÀÖ´Â clientÀÇ ¼öÀÌ´Ù. Áï Queue sizeÀÎ °ÍÀÌ´Ù. listenÀÌ 1À̸é server¿Í Á¢¼ÓÇϱâ À§ÇØ ÁöÁ¤µÈ QueueÀÇ sizeÀÌ´Ù. ù ¹ø° client´Â Queue¿¡ ´ë±â ÇÒ ÇÊ¿ä ¾øÀÌ server¿Í ¹Ù·Î connect°¡ ÀÌ·ç¾îÁö°í, µÎ ¹ø° client´Â Queue¿¡ µé¾î°¡°Ô µÈ´Ù. ¼¼ ¹ø° client´Â Queue¿¡ µé¾î °¥ ¼ö ¾ø±â¿¡ connect°¡ µÉ ¼ö ¾ø´Ù. ±×·¯³ª ù ¹ø° ¿Í µÎ ¹ø° client°¡ data¸¦ º¸³»°í Á¢¼Ó Á¾·áÇÏ¿´À» ¶§ ¼¼ ¹ø° client°¡ connect°¡ µÈ °ÍÀº ù ¹ø° client°¡ Á¢¼Ó Á¾·áÈÄ µÎ ¹ø° client°¡ connectµÇ°í Queue°¡ ºñ¿öÁöÀÚ ¼¼ ¹ø° client°¡ Queue·Î µé¾î°¡¼ connectµÈ °ÍÀÌ´Ù.
6-5. server°¡ accept¸¦ ÇÏÁö ¾ÊÀº °æ¿ì?
¨ç µ¿ÀÛ È¯°æ server°¡ accept¸¦ ÇÏ°Ô µÇ¸é clientÀÇ data¸¦ Csock¿¡ ÀúÀåÇÏ°í recv, send½Ã¿¡ clientÀÇ Á¤º¸¸¦ ¾Ë·ÁÁØ´Ù. server.c´Â ¾Æ·¡¿Í °°ÀÌ accept ºÎºÐÀ» ÁÖ¼® ó¸®ÇÑ´Ù. client.c´Â connectµÇ±â Àü¿¡ º¸³¾ data¸¦ ÀԷ¹޴´Ù. server port´Â 8007¹øÀÌ´Ù.
/* -------------------------------------------------------------------- */ /* Case 6-5) : Accept ÇÔ¼öÀÇ ±â´É (TCP Socket) */ /* 1) Server°¡ accept()¸¦ ÇÏÁö ¾ÊÀº °æ¿ì ¾î¶»°Ô µÇ³ª ? */ /* -------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h>
#define ServicePort 8007 #define MSG "Server processed successfully according your requests."
int main() { int pid, num; int Rsock, Csock; // Socket Descriptor char ServerName[20]; // Server Domain Name int ClientAddrLen; // Client Address Length char buf[80]; // Receiving Buffer struct sockaddr_in SockAddr; struct sockaddr_in ClientAddr; // struct sockaddr ClientAddr;
if (gethostname(ServerName, sizeof(ServerName))) { printf("Server Error! gethostname() error\n"); exit(-1); } printf("\n[Server] server name: %s\n", ServerName); if ((Rsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Server Error! socket() error"); exit(-1); } printf("[Server] Socket created.\n");
bzero((char*) &SockAddr, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr.sin_port = htons(ServicePort);
if (bind(Rsock, (struct sockaddr *) &SockAddr, sizeof(SockAddr))) { printf("Server Error! bind() error"); exit(-1); } printf("[Server] Socket binded.\n");
if (listen(Rsock, 5)) { printf("Server Error! listen() error"); exit(-1); } printf("[Server] Socket listened.\n");
printf("If continue, enter any number. "); scanf("%d", &num); /* while (1) { */ printf("[Server] Waiting for connection request.\n\n"); /* Updated! for checking accept() ClientAddrLen = sizeof(ClientAddr); if ((Csock = accept(Rsock, (struct sockaddr *) &ClientAddr, &ClientAddrLen)) < 0) { printf("Server Error! accept() error\n"); printf("Rsock = %d Csock = %d\n", Rsock, Csock); exit(-1); } printf("[Server] Client(%s) and Server Connected.\n", inet_ntoa(ClientAddr.sin_addr)); */ printf("[Server] Created child process.\n");
if ((pid = fork()) < 0 ) { printf("Server Error! fork() error"); exit(-1); } else if (pid == 0) { /* Child Process */ close(Rsock); printf("[Child] Waiting for client data.\n"); if ((num = recv(Csock, buf, sizeof(buf), 0)) < 0) { printf("[Child] Receive Error!\n"); exit(-1); } printf("[Child] Data from Client(%s:%d) [%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf); send(Csock, MSG, (sizeof(MSG)), 0); printf("[Child] Sent response message to client.\n"); printf("[Child] Exit.\n"); close(Csock); // Be Careful! exit(0); } else if (pid > 0) { /* Parent Process */ // close(Csock); } /* } */ }
¨è ½ÇÇà °á°ú
server : server ÇÁ·Î±×·¥À» ½ÇÇà. Á¤¼ö¸¦ ÀÔ·ÂÇÏ°Ô µÇ¸é accept¸¦ ¼öÇàÇÏÁö ¾Ê°í client¿Í connect ¿äûÀ» ¹Þ´Â´Ù.
server : client·ÎºÎÅÍ data¸¦ Àü¼Û ¹ÞÀÚ Receive Error°¡ ³´Ù.
¨é °á°ú ºÐ¼® server°¡ accept¸¦ ÇÏÁö ¾ÊÀ» °æ¿ì ÄÄÆÄÀÏ ½Ã ¿¡·¯´Â ³ªÁö ¾ÊÀ¸³ª runtime½Ã Receive Error°¡ ³´Ù. ÀÌ´Â accept°¡ connectÇÏ´Â °úÁ¤ÀÇ Çϳª°¡ ¾Æ´Ï¶ó data¸¦ ÁÖ°í¹ÞÀ» ¶§ serverÀÇ Á¤º¸¸¦ °¡Áö°í ¼·ÎÀÇ Åë½Å·Î¸¦ È®¸³ÇØ ÁÖ´Â ÀÏÀ» Çϱ⠶§¹®ÀÌ´Ù.
1) send(), recv()´Â ¾î¶² ¸ðµå·Î µ¿ÀÛÇϴ°¡ ?
¨ç µ¿ÀÛ ¼³¸í send()°¡ ¾î¶² ¸ðµåÀÎÁö È®ÀÎÇϱâ À§Çؼ´Â client°¡ data¸¦ º¸³»°í server°¡ data¸¦ ¹ÞÁö ¾Ê°í ´ë±âÇÏ°í ÀÖÀ» clientÀÇ »óŸ¦ ÆľÇÇÑ´Ù. recv()´Â ±âº»¿¹Á¦·Î »ìÆ캸ÀÚ.
/* --------------------------------------------------------------------- */ /* server.c */ /* Case 6-6) : send´Â ¾î¶² ¸ðµå Àΰ¡ ? */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.03.10 */ /* -------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> // ¿©·¯ °¡Áö Á¤ÀÇµÈ ÀÚ·áÇü µéÀ» »ç¿ëÇϱâ À§ÇØ #include <sys/socket.h> // socket°ú °ü·ÃµÈ ±¸Á¶Ã¼¿Í ÀÚ·áÇü µéÀ» »ç¿ëÇϱâ À§ÇØ #include <netdb.h> // socket°ú °ü·ÃµÈ ÇÔ¼ö¿Í ±¸Á¶Ã¼¸¦ »ç¿ëÇϱâ À§ÇØ #include <netinet/in.h> // socketaddr_in ±¸Á¶Ã¼¸¦ »ç¿ëÇϱâ À§ÇØ #include <arpa/inet.h> // ALPA internet protocol°ú °ü·Ã µÈ ±¸Á¶Ã¼¸¦ »ç¿ëÇϱâ À§ÇØ
#define ServicePort 8001 #define MSG "Server processed successfully according your requests."
int main() { int pid, num; int Rsock, Csock; // Socket Descriptor char ServerName[20]; // Server Domain Name int ClientAddrLen; // Client Address Length char buf[80]; // Receiving Buffer struct sockaddr_in SockAddr; struct sockaddr_in ClientAddr; // Updated! for Client Addr if (gethostname(ServerName, sizeof(ServerName))) { printf("Server Error! gethostname() error\n"); exit(-1); } printf("\n[Server] server name: %s\n", ServerName);
if ((Rsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Server Error! socket() error"); exit(-1); } printf("[Server] Socket created.\n");
bzero((char*) &SockAddr, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr.sin_port = htons(ServicePort);
if (bind(Rsock, (struct sockaddr *) &SockAddr, sizeof(SockAddr))) { printf("Server Error! bind() error"); exit(-1); } printf("[Server] Socket binded.\n");
if (listen(Rsock, 5)) { printf("Server Error! listen() error"); exit(-1); } printf("[Server] Socket listened.\n");
while (1) { printf("[Server] Waiting for connection request.\n\n");
ClientAddrLen = sizeof(ClientAddr); if ((Csock = accept(Rsock, (struct sockaddr *) &ClientAddr, &ClientAddrLen)) < 0) { printf("Server Error! accept() error\n"); printf("Rsock = %d Csock = %d\n", Rsock, Csock); exit(-1); } printf("[Server] Client(%s) and Server Connected.\n", inet_ntoa(ClientAddr.sin_addr)); printf("[Server] Created child process.\n"); if ((pid = fork()) < 0 ) { printf("Server Error! fork() error"); exit(-1); } else if (pid == 0) { /* Child Process */ close(Rsock); printf("[Child] Waiting for client data.\n");
// Update ! send°¡ blocking ÀÎÁö¸¦ Test. printf("If continue, enter any number. "); scanf("%d", &num); if ((num = recv(Csock, buf, sizeof(buf), 0)) < 0) { printf("[Child] Receive Error!\n"); exit(-1); } printf("[Child] Data from Client(%s:%d) [%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf);
send(Csock, MSG, (sizeof(MSG)), 0); printf("[Child] Sent response message to client.\n"); printf("[Child] Exit.\n"); close(Csock); // Be Careful! exit(0); } else if (pid > 0) { /* Parent Process */ close(Csock); } } }
/* --------------------------------------------------------------------- */ /* client.c */ /* Case 6-6) : send´Â ¾î¶² ¸ðµåÀΰ¡ ? */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.03.10 */ /* --------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <string.h>
#define MAXSIZE 512 #define ServicePort 8001
int main(int argc, char *argv[]) { int sd; struct in_addr *InetAddr; struct sockaddr_in ServerSockAddr; struct hostent *ServerInfo; char SndBuf[MAXSIZE], RcvBuf[MAXSIZE];
if ((ServerInfo = gethostbyname(argv[1])) == NULL) { printf("Client Error! gethostbyname() error\n"); exit(-1); } InetAddr = (struct in_addr *) *(ServerInfo->h_addr_list); printf("[Client] sever address %s \n", inet_ntoa(*InetAddr));
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { printf("Client Error! socket() error \n"); exit(-1); } printf("[Client] Socket created.\n");
bzero((char*) &ServerSockAddr, sizeof(ServerSockAddr)); ServerSockAddr.sin_family = AF_INET; ServerSockAddr.sin_addr.s_addr = InetAddr->s_addr; ServerSockAddr.sin_port = htons(ServicePort);
printf("[Client] Clint sent connection request.\n"); if (connect(sd, (struct sockaddr *) &ServerSockAddr, sizeof(ServerSockAddr)) < 0) { printf("Client Error! connect() error\n"); exit(-1); } printf("[Client] Clint and server connected.\n");
printf("[Client] Input Data ? "); gets(SndBuf);
send(sd, SndBuf, (sizeof(SndBuf)), 0); //send() mode¸¦ Test -- Updated printf("send() is nonblocking");
recv(sd, RcvBuf, (sizeof(RcvBuf)), 0); printf("[Client] Client received Data.\n");
printf("[Client] Data from Server [%s]\n", RcvBuf);
close(sd); printf("[Client] Client Exit.\n"); }
¨è ½ÇÇà °á°ú
server : server¸¦ ½ÇÇà½ÃÅ°°í ÀÓÀÇÀÇ ¼ö¸¦ ÀԷ¹ÞÀ» ¶§±îÁö ´ë±âÇÑ´Ù.
client : data¸¦ º¸³ÂÀ¸³ª serverÃø¿¡¼ recv() ¼öÇàÇÏÁö ¾ÊÀÚ client´Â °è¼Ó ´ë±âÇÏ°í ÀÖ´Ù.
¨é °á°ú ºÐ¼® send()´Â blocking mode·Î µ¿ÀÛÇÑ´Ù. client¿¡¼ data¸¦ º¸³»°í server¿¡¼ recv()°¡ ¼öÇàµÉ ¶§±îÁö block »óÅ·Π´ë±âÇÑ´Ù. recv()µµ blocking mode·Î µ¿ÀÛÇÑ´Ù. ±âº»¿¹Á¦ ¼öÇà °á°ú¸¦ º¸°í ¾Ë ¼ö Àִµ¥ server¿Í client°¡ Á¢¼ÓÀÌ ÀÌ·ç¾îÁø »óÅ¿¡¼ server´Â client·ÎºÎÅÍ data¸¦ Àü´Þ¹ÞÀ» ¶§±îÁö block »óÅ·Π´ë±âÇÑ´Ù.
2) accept¿Í connect´Â ¾î¶² mode·Î µ¿ÀÛÇϴ°¡?
¨ç µ¿ÀÛ ¼³¸í accept°¡ ¾î¶² ¸ðµåÀÎÁö´Â ±âº»¿¹Á¦¿¡¼ È®ÀÎ ÇÒ ¼ö ÀÖ´Ù. connect°¡ ¾î¶² ¸ðµåÀÎÁö¸¦ ¾Ë±â À§Çؼ´Â client°¡ connect request¸¦ server¿¡°Ô º¸³ÂÀ» ¶§ server°¡ connect request¸¦ ¹ÞÁö ¾ÊÀ» ¶§¸¦ È®ÀÎÇÏ¸é ¾Ë ¼ö ÀÖ´Ù.
/* --------------------------------------------------------------------- */ /* server.c */ /* Case 6-6) : connect()´Â ¾î¶² mode·Î µ¿ÀÛÇϴ°¡ */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.03.10 */ /* --------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h>
#define ServicePort 8001 #define MSG "Server processed successfully according your requests."
int main() { int pid, num; int Rsock, Csock; // Socket Descriptor char ServerName[20]; // Server Domain Name int ClientAddrLen; // Client Address Length char buf[80]; // Receiving Buffer struct sockaddr_in SockAddr; struct sockaddr_in ClientAddr;
if (gethostname(ServerName, sizeof(ServerName))) { printf("Server Error! gethostname() error\n"); exit(-1); } printf("\n[Server] server name: %s\n", ServerName);
if ((Rsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Server Error! socket() error"); exit(-1); } printf("[Server] Socket created.\n");
bzero((char*) &SockAddr, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr.sin_port = htons(ServicePort);
if (bind(Rsock, (struct sockaddr *) &SockAddr, sizeof(SockAddr))) { printf("Server Error! bind() error"); exit(-1); } printf("[Server] Socket binded.\n");
if (listen(Rsock, 5)) { printf("Server Error! listen() error"); exit(-1); } printf("[Server] Socket listened.\n");
while (1) { //Updata - connect°¡ ¾î¶² ¸ðµåÀÎÁö È®ÀÎ printf("If continue, enter any number. "); scanf("%d", &num);
printf("[Server] Waiting for connection request.\n\n");
ClientAddrLen = sizeof(ClientAddr); if ((Csock = accept(Rsock, (struct sockaddr *) &ClientAddr, &ClientAddrLen)) < 0) { printf("Server Error! accept() error\n"); printf("Rsock = %d Csock = %d\n", Rsock, Csock); exit(-1); } printf("[Server] Client(%s) and Server Connected.\n", inet_ntoa(ClientAddr.sin_addr)); printf("[Server] Created child process.\n");
if ((pid = fork()) < 0 ) { printf("Server Error! fork() error"); exit(-1); } else if (pid == 0) { /* Child Process */ close(Rsock); printf("[Child] Waiting for client data.\n");
if ((num = recv(Csock, buf, sizeof(buf), 0)) < 0) { printf("[Child] Receive Error!\n"); exit(-1); } printf("[Child] Data from Client(%s:%d) [%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf);
send(Csock, MSG, (sizeof(MSG)), 0); printf("[Child] Sent response message to client.\n");
printf("[Child] Exit.\n"); close(Csock); // Be Careful! exit(0); } else if (pid > 0) { /* Parent Process */ close(Csock); } } }
/* --------------------------------------------------------------------- */ /* client.c */ /* Case 6-6) : connect()´Â ¾î¶² mode·Î µ¿ÀÛÇϴ°¡ */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.03.10 */ /* --------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <string.h>
#define MAXSIZE 512 #define ServicePort 8001
int main(int argc, char *argv[]) { int sd; struct in_addr *InetAddr; struct sockaddr_in ServerSockAddr; struct hostent *ServerInfo; char SndBuf[MAXSIZE], RcvBuf[MAXSIZE];
if ((ServerInfo = gethostbyname(argv[1])) == NULL) { printf("Client Error! gethostbyname() error\n"); exit(-1); } InetAddr = (struct in_addr *) *(ServerInfo->h_addr_list); printf("[Client] sever address %s \n", inet_ntoa(*InetAddr));
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { printf("Client Error! socket() error \n"); exit(-1); } printf("[Client] Socket created.\n");
bzero((char*) &ServerSockAddr, sizeof(ServerSockAddr)); ServerSockAddr.sin_family = AF_INET; ServerSockAddr.sin_addr.s_addr = InetAddr->s_addr; ServerSockAddr.sin_port = htons(ServicePort);
printf("[Client] Clint sent connection request.\n"); if (connect(sd, (struct sockaddr *) &ServerSockAddr, sizeof(ServerSockAddr)) < 0) { printf("Client Error! connect() error\n"); exit(-1); } printf("[Client] connect is nonblocking.\n");
printf("[Client] Input Data ? "); gets(SndBuf);
send(sd, SndBuf, (sizeof(SndBuf)), 0); printf("[Client] Client sent Data.\n");
recv(sd, RcvBuf, (sizeof(RcvBuf)), 0); printf("[Client] Client received Data.\n");
printf("[Client] Data from Server [%s]\n", RcvBuf);
close(sd); printf("[Client] Client Exit.\n"); } ¨è ½ÇÇà °á°ú
server : accept() ¹Ù·Î ¾Õ¿¡¼ ÇÁ·Î±×·¥À» ¸ØÃß°Ô ÇÏ¿´´Ù.
client : server·Î connect ¿äûÀ» ÇÏ¿´´Ù. server°¡ accept¸¦ ÇÏÁö ¾Ê°í ´ë±â¸¸ ÇÏ¿´Áö¸¸ client´Â ´ÙÀ½ ¸í·ÉÀ» ¼öÇàÇÏ´Â ¸ð½ÀÀ» º¼ ¼ö ÀÖ´Ù.
¨é °á°ú ºÐ¼® accept´Â ±âº»¿¹Á¦¿¡¼ º¸µíÀÌ client°¡ connect request¸¦ º¸³¾ ¶§±îÁö blocking mode·Î ´ë±âÇÏ°í ÀÖÀ½À» ¾Ë ¼ö ÀÖ´Ù. connect´Â À§ÀÇ ½ÇÇà °á°úó·³ client°¡ connect¸¦ ¿äûÇÏ°í server´Â accept¸¦ ÇÏÁö ¾Ê°í ¸ØÃçÁ® ÀÖ¾ú´Ù. ±×·¯³ª client´Â connect request¸¦ ¹Þ¾Æµé¿©Áö´Â °Í°ú »ó°ü¾øÀÌ ´ÙÀ½ ¸í·ÉÀ» ¼öÇàÇÔÀ¸·Î¼ nonblockingÀÓÀ» ¾Ë ¼ö ÀÖ´Ù.
6-7. º¹¼öÀÇ Åë½Å·Î¸¦ ¿¾úÀ» ¶§?
¨ç µ¿ÀÛ ¼³¸í »ý¼ºµÈ ÇϳªÀÇ Socket¿¡ µÎ °³ÀÇ port¸¦ bindingÇØ¾ß µÇÁö¸¸ ÇϳªÀÇ Socket¿¡ µÎ °³ÀÇ port¸¦ binding ÇÒ ¼ö ¾ø¾î °¢ °¢ socketÀ» »ý¼º, binding, listen, send, recv¸¦ ÇÑ´Ù. ±×·¯±â À§ÇØ server.c¿Í client.c¸¦ °¢°¢ ¾Æ·¡¿Í °°ÀÌ ¼öÁ¤ÇÑ´Ù. service port´Â 9005, 9006¹øÀÌ´Ù.
/* --------------------------------------------------------------------- */ /* server.c */ /* Case6-7) : º¹¼öä³ÎÀ» ÀÌ¿ëÇÑ Åë½Å (Server 2 : Client 2) */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* --------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h>
#define ServicePort1 9005 // Updated!! Chanel 1 Port #define ServicePort2 9006 // Updated!! Chanel 2 Port #define MSG "Server processed successfully according your requests."
//Updated!! Add to Function Loop void Loop(int Rsock, int Csock, struct sockaddr_in C_addr, int i); int main() { int pid; int Rsock1, Rsock2, Csock1, Csock2; // Updated!! Two Socket Descriptor char ServerName[20]; // Server Domain Name struct sockaddr_in SockAddr1, SockAddr2; // Updated! for Server Address struct struct sockaddr_in ClientAddr1, ClientAddr2; // Updated! for Client
if (gethostname(ServerName, sizeof(ServerName))) { printf("Server Error! gethostname() error\n"); exit(-1); } printf("\n[Server] server name: %s\n", ServerName);
if ((Rsock1 = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Server 1 Error! socket() error"); exit(-1); } printf("[Server 1] Socket created.\n");
//Updated!! Created Chanel 2 Socket if ((Rsock2 = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Server 2 Error! socket() error"); exit(-1); } printf("[Server 2] Socket created.\n");
bzero((char*) &SockAddr1, sizeof(SockAddr1)); SockAddr1.sin_family = AF_INET; SockAddr1.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr1.sin_port = htons(ServicePort1);
bzero((char*) &SockAddr2, sizeof(SockAddr2)); //Updated! Adderess Chanel 2 SockAddr2.sin_family = AF_INET; SockAddr2.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr2.sin_port = htons(ServicePort2);
if (bind(Rsock1, (struct sockaddr *) &SockAddr1, sizeof(SockAddr1))) { printf("Server 1 Error! bind() error"); exit(-1); } printf("[Server 1] Socket binded.\n");
// Updated! Binded Chanel 2 if (bind(Rsock2, (struct sockaddr *) &SockAddr2, sizeof(SockAddr2))) { printf("Server 2 Error! bind() error"); exit(-1); } printf("[Server 2] Socket binded.\n");
if (listen(Rsock1, 5)) { printf("Server 1 Error! listen() error"); exit(-1); } printf("[Server 1] Socket listened.\n");
if (listen(Rsock2, 5)) { printf("Server 2 Error! listen() error"); exit(-1); } printf("[Server 2] Socket listened.\n"); // Updated!! listened Chanel 2
if ((pid = fork()) < 0 ) // Updated!! for each chanel process { printf("Server fork() error !! "); exit(-1); } else if (pid == 0) { close(Rsock2); Loop(Rsock1,Csock1,ClientAddr1,1); } else if (pid > 0) { close(Rsock1); Loop(Rsock2,Csock2,ClientAddr2,2); } }
void Loop(int Rsock, int Csock, struct sockaddr_in C_addr, int i) { char buf[80]; int num; int ClientAddrLen; int pid; while(1) { ClientAddrLen = sizeof(C_addr); if ((Csock = accept(Rsock, (struct sockaddr *) &C_addr, &ClientAddrLen)) < 0 ) { printf("Server %d Error! accept() error\n",i); printf("Rsock = %d Csock = %d\n", Rsock, Csock); exit(-1); } printf("[Server %d] Client (%s:%d) and server Connected.\n",i, inet_ntoa(C_addr.sin_addr),C_addr.sin_port); printf("[Server %d] Created child process.\n",i); if ((pid=fork()) < 0) { printf("Server Error! fork() error"); exit(-1); } else if (pid == 0) { close(Rsock); printf("[Server %d:Child] Waiting for client data.\n",i); if ((num = recv(Csock, buf, sizeof(buf), 0)) < 0) { printf("[Server %d:Child] Receive Error!\n",i); exit(-1); } printf("[Server %d:Child] Data from Client(%s:%d) [%s]\n",i,inet_ntoa(C_addr.sin_addr), C_addr.sin_port, buf); send(Csock, MSG, (sizeof(MSG)), 0); printf("[Server %d:Child] Sent response message to client.\n",i); printf("[Server %d:Child] Exit.\n",i); exit(0); } else if (pid > 0) { close(Csock); } } }
/* -------------------------------------------------------------------- */ /* client.c */ /* Case6-7) : º¹¼öä³ÎÀ» ÀÌ¿ëÇÑ Åë½Å (Server 2 : Client 2) */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* -------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <string.h>
#define MAXSIZE 512 #define ServicePort1 9005 #define ServicePort2 9006
int main(int argc, char *argv[]) { int sd, pid; struct in_addr *InetAddr; struct sockaddr_in ServerSockAddr1, ServerSockAddr2; struct hostent *ServerInfo; char SndBuf1[MAXSIZE], RcvBuf1[MAXSIZE]; char SndBuf2[MAXSIZE], RcvBuf2[MAXSIZE];
if ((ServerInfo = gethostbyname(argv[1])) == NULL) { printf("Client Error! gethostbyname() error\n"); exit(-1); } InetAddr = (struct in_addr *) *(ServerInfo->h_addr_list); printf("[Client] sever address %s \n", inet_ntoa(*InetAddr)); printf("[Client] Input Data to send to Server 1 ? "); gets(SndBuf1); printf("[Client] Input Data to send to Server 2 ? "); gets(SndBuf2); if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { printf("Client Error! socket() error \n"); exit(-1); } printf("[Client] Socket created.\n");
bzero((char*) &ServerSockAddr1, sizeof(ServerSockAddr1)); ServerSockAddr1.sin_family = AF_INET; ServerSockAddr1.sin_addr.s_addr = InetAddr->s_addr; ServerSockAddr1.sin_port = htons(ServicePort1);
bzero((char*) &ServerSockAddr2, sizeof(ServerSockAddr2)); ServerSockAddr2.sin_family = AF_INET; ServerSockAddr2.sin_addr.s_addr = InetAddr->s_addr; ServerSockAddr2.sin_port = htons(ServicePort2);
printf("[Client] Clint sent connection request.\n\n"); if ((pid=fork()) <0 ) { printf("Client error !! fork() error\n"); exit(-1); } else if (pid == 0) { if (connect(sd, (struct sockaddr *) &ServerSockAddr1, sizeof(ServerSockAddr1)) < 0) { printf("Client Error! connect() Server 1 error\n"); exit(-1); } printf("[Client] Client and server 1 connected.\n"); send(sd, SndBuf1, (sizeof(SndBuf1)), 0); printf("[Client] Client sent Data to server 1.\n"); recv(sd, RcvBuf1, (sizeof(RcvBuf1)), 0); printf("[Client] Client received Data from server 1.\n"); printf("[Client] Data from Server [%s]\n", RcvBuf1); close(sd); printf("[Client] Client Exit - server 1.\n"); } else if (pid > 0) { if (connect(sd, (struct sockaddr *) &ServerSockAddr2, sizeof(ServerSockAddr2)) < 0) { printf("Client Error! connect() Server 2 error\n"); exit(-1); } printf("[Client] Client and server 2 connected.\n"); send(sd, SndBuf2, (sizeof(SndBuf2)), 0); printf("[Client] Client sent Data to server 2.\n"); recv(sd, RcvBuf2, (sizeof(RcvBuf2)), 0); printf("[Client] Client received Data from server 2.\n"); printf("[Client] Data from Server [%s]\n", RcvBuf2); close(sd); printf("[Client] Client Exit - server 2.\n"); } exit(0); }
¨è ½ÇÇà °á°ú
server : server ÇÁ·Î±×·¥À» ½ÇÇà½ÃŲ´Ù.
netstat : °¢ °¢ socketÀÌ bindingÇÑ °ÍÀ» º¼ ¼ö ÀÖ´Ù.
client : °¢ data¸¦ server·Î Àü¼ÛÇß´Ù.
server : °¢ data¸¦ Àü´Þ¹Þ°í ÀÀ´ä ¸Þ½ÃÁö¸¦ º¸³Â´Ù.
¨é °á°ú ºÐ¼® »ý¼ºµÈ ÇϳªÀÇ socket¿¡ µÎ °³ÀÇ port¸¦ bind ÇÒ ¼ö ¾ø´Ù. µû¶ó¼ À§¿Í °°ÀÌ TestÇÏ¿´´Ù. ¶ÇÇÑ ÇϳªÀÇ Process´Â Çѹø¸¸ acceptµÇ¸ç, Çѹø¸¸ connect µÇ°í, ÇϳªÀÇ Åë½Å ä³Î¸¸À» °¡Áø´Ù.
6-8. UDP Socket Åë½ÅÀÇ Æ¯Â¡°ú ±âº» ÀýÂ÷¸¦ ¾Ë¾Æº¸ÀÚ.
¨ç µ¿ÀÛ È¯°æ. ±âº» Çü½ÄÀ» TCPÀÇ ±âº»¿¹Á¦¸¦ ¹ÙÅÁÀ¸·Î ¸¸µé¾úÀ¸¸ç, UDP Ư¼º»ó listen°ú acceptµîÀ» »ç¿ëÇÏÁö ¾Ê¾ÒÀ¸¹Ç·Î Process¸¦ forkÇÒ ÇÊ¿äµµ ¾ø¾ú´Ù. serverÀÇ service port´Â 5800ÀÌ°í clientÀÇ service port´Â 5801ÀÌ´Ù.
/* --------------------------------------------------------------------- */ /* server.c */ /* Case 6-8) : UDP SocketÀÇ Æ¯Â¡°ú ±âº» ÀýÂ÷¸¦ ¾Ë¾Æº¸ÀÚ (UDP Socket) */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* --------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h>
#define ServicePort 5800 #define MSG "Server processed successfully according your requests."
int main() { int pid, num; int Rsock; // Socket Descriptor char ServerName[20]; // Server Domain Name int ClientAddrLen; // Client Address Length char buf[80]; // Receiving Buffer struct sockaddr_in SockAddr; struct sockaddr_in ClientAddr;
if (gethostname(ServerName, sizeof(ServerName))) { printf("Server Error! gethostname() error\n"); exit(-1); } printf("\n[Server] server name: %s\n", ServerName);
if ((Rsock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { printf("Server Error! socket() error"); exit(-1); } printf("[Server] Socket created.\n");
bzero((char*) &SockAddr, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr.sin_port = htons(ServicePort);
if (bind(Rsock, (struct sockaddr *) &SockAddr, sizeof(SockAddr))) { printf("Server Error! bind() error"); exit(-1); } printf("[Server] Socket binded.\n");
while (1) { printf("[Child] Waiting for client data.\n"); if ((num = recvfrom(Rsock, buf, sizeof(buf), 0,(struct sockaddr *)&ClientAddr,&ClientAddrLen)) < 0) { printf("[Server] Receive Error!\n"); exit(-1); } printf("[Child] Data from Client(%s:%d) [%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf); sendto(Rsock, MSG, (sizeof(MSG)), 0,(struct sockaddr *)&ClientAddr,sizeof(struct sockaddr)); printf("[Child] Sent response message to client.\n"); } }
/* -------------------------------------------------------------------- */ /* client.c */ /* Case 6-8) : UDP SocketÀÇ Æ¯Â¡°ú ±âº» ÀýÂ÷¸¦ ¾Ë¾Æº¸ÀÚ (UDP Socket) */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* -------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h>
#include <netdb.h> #include <netinet/in.h> #include <string.h>
#define MAXSIZE 512 #define ServerPort 5800 #define ClientPort 5801
int main(int argc, char *argv[]) { int sd,num,addr_len; struct in_addr *InetAddr; struct sockaddr_in ServerSockAddr; struct sockaddr_in ClientSockAddr; struct hostent *ServerInfo; char SndBuf[MAXSIZE], RcvBuf[MAXSIZE],SndBu[20];
if ((ServerInfo = gethostbyname(argv[1])) == NULL) { printf("Client Error! gethostbyname() error\n"); exit(-1); }
InetAddr = (struct in_addr *) *(ServerInfo->h_addr_list); printf("[Client] sever address %s \n", inet_ntoa(*InetAddr));
if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { printf("Client Error! socket() error \n"); exit(-1); } printf("[Client] Socket created.\n");
bzero((char*) &ServerSockAddr, sizeof(ServerSockAddr)); ServerSockAddr.sin_family = AF_INET; ServerSockAddr.sin_addr.s_addr = InetAddr->s_addr; ServerSockAddr.sin_port = htons(ServerPort);
bzero((char*) &ClientSockAddr, sizeof(ClientSockAddr)); ClientSockAddr.sin_family = AF_INET; ClientSockAddr.sin_addr.s_addr = htonl(INADDR_ANY); ClientSockAddr.sin_port = htons(ClientPort);
if (bind(sd,(struct sockaddr *)&ClientSockAddr,sizeof(struct sockaddr))) { printf("Client Error! bind() error"); exit(1); } printf("[Client] Input Data ? "); gets(SndBuf);
sendto(sd, SndBuf, sizeof(SndBuf), 0,(struct sockaddr *)&ServerSockAddr,sizeof(struct sockaddr)); printf("[Client] Client sent Data.\n"); recvfrom(sd, RcvBuf, sizeof(RcvBuf), 0,(struct sockaddr*)&ServerSockAddr,&addr_len); printf("[Client] Client received Data.\n"); printf("[Client] Data from Server [%s]\n", RcvBuf);
close(sd); printf("[Client]Client Exit.\n"); return 0; }
¨è ½ÇÇà ȯ°æ
server : server ÇÁ·Î±×·¥À» ½ÇÇàÇÑ È¸é
client : Àü´Þ¹ÞÀ» data¸¦ °¡Áö°í server·Î Á¢¼ÓÇÏ·Á°í ÇÑ´Ù.
netstat : server¿Í clientÀÇ ¸ð½ÀÀ» È®ÀÎ ÇÒ ¼ö ÀÖ´Ù
netstat : data¸¦ Àü´Þ¹Þ°í client´Â Á¾·á µÈ ȸéÀÌ´Ù..
¨é °á°ú ºÐ¼® TCP¿Í UDP´Â Á¶±ÝÀÇ Â÷ÀÌÁ¡À» °¡Áö°í ÀÖ´Ù. ¸ÕÀú TCP´Â ¿À·ùÁ¦¾î, È帧Á¦¾î, ½ÃÄö½º Á¦¾î¸¦ Çϱ⠶§¹®¿¡ µ¥ÀÌÅÍÀÇ ¾ÈÁ¤¼ºÀÌ º¸ÀåµÇ³ª UDP´Â data Á¦¾î ¾øÀÌ º¸³»±â ¶§¹®¿¡ ¾ÈÁ¤¼ºÀ» º¸Àå¹ÞÀ» ¼ö ¾ø´Ù. UDP data Á¦¾î¸¦ ÇÏÁö ¾Ê±â ¶§¹®¿¡ TCP Åë½Åº¸´Ù ¼Óµµ°¡ ÈξÀ ºü¸£´Ù´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. SourceÀÇ È帧»ó ´Ù¸¥ Á¡Àº UDP´Â clientµµ bind¸¦ ÇÑ´Ù´Â Á¡ÀÌ´Ù. ºñ¿¬°áÁöÇâÀûÀ̱⠶§¹®ÀÌ´Ù. ±×¸®°í listen°ú accept¸¦ ÇÏÁö ¾Ê¾Æµµ µÈ´Ù´Â °ÍÀÌ´Ù. ÀÌ ¶ÇÇÑ ºñ¿¬°áÁöÇâÀûÀ̱⠶§¹®ÀÌ´Ù.
6-9. UDP Socket Åë½Å¿¡¼ ¿À·ùÁ¦¾î¸¦ È®ÀÎÇϱâ À§ÇØ ´ë¿ë·® data¸¦ º¸³»¸é?
¨ç µ¿ÀÛ È¯°æ client°¡ server·Î ¿ì¸® ³ª¶ó ¿ìÆí¹øÈ£¸¦ ¸ðµÎ ¼ö·ÏÇÑ zipcode.txt¸¦ º¸³¾ ¶§ Á¤È®ÇÏ°Ô data¸¦ ¸ðµÎ Àü´Þ¹Þ´ÂÁö È®ÀÎÇÑ´Ù. server.c¿Í client.c´Â ¾Æ·¡¿Í °°´Ù. serverÀÇ service port´Â 5800ÀÌ°í, clientÀÇ service port´Â 5801ÀÌ´Ù.
/* ------------------------------------------------------------------- */ /* server.c */ /* Case 6-9) : UDP SocketÀ» ÀÌ¿ëÇÑ Åë½Å */ /* ¿À·ùÁ¦¾î¸¦ È®ÀÎÇϱâ À§ÇØ ´ë¿ë·® data Àü´Þ */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* ------------------------------------------------------------------- */
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <netinet/in.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h>
#define ServicePort 5800 #define BUFFERSIZE 4096 #define MSG "Server processed successfully according your requests."
main() { int sock, i; int addr_len, bytes; char ServerName[20]; char buf[BUFFERSIZE]; struct sockaddr_in SockAddr; /* my address information */ struct sockaddr_in ClientAddr; /* connector's address information */
if(gethostname(ServerName, sizeof(ServerName))){ printf("Server Error! gethostname() error\n"); exit(-1); } printf("\n[Server] server name:%s\n", ServerName);
//Updated : ¼ÒÄÏÀÇ À¯ÇüÁöÁ¤(UDP) if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { printf("Server Error! socket() error"); exit(1); } printf("[Server] Socket created.\n");
bzero((char*) &SockAddr, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr.sin_port = htons(ServicePort);
if (bind (sock,(struct sockaddr *)&SockAddr, sizeof(struct sockaddr))) { printf("Server Error! bind() error"); exit(1); } printf("[Server] Socket binded.\n");
addr_len = sizeof(struct sockaddr); while(1){ printf("[Child] Waiting for client data.\n");
//Updated : recvfromÀ¸·Î clientÃø¿¡¼ sendto·Î º¸³½ ³»¿ëÀ» ¹öÆÛ´ÜÀ§ ¸¸Å ÀÐÀº µ¥ÀÌÅÍÀÇ ¹ÙÀÌÆ®¼ö ¹Ýȯ if ((bytes=recvfrom(sock, buf, BUFFERSIZE, 0,(struct sockaddr *)&ClientAddr, &addr_len)) == -1){ printf("Server Error! recvfrom() error"); exit(1); } buf[bytes] = '\0'; printf("Data from Client(%s:%d)\n[%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port,buf); for(i=0; i<BUFFERSIZE; i++) buf[i]=NULL;
//Updated : sendto·Î Ŭ¶óÀ̾ðÆ®ÃøÀ¸·Î MSGÀÇ ¸Þ¼¼Áö¸¦ º¸³½´Ù. if ((bytes=sendto(sock, MSG, strlen(MSG), 0, (struct sockaddr *)&ClientAddr, sizeof(struct sockaddr))) == -1){ printf("Client Error! sendto() error"); exit(1); } printf("Sent response message to client.\n"); } close(sock); }
/* -------------------------------------------------------------------- */ /* client.c */ /* Case 6-9) : UDP SocketÀ» ÀÌ¿ëÇÑ Åë½Å */ /* ¿À·ùÁ¦¾î¸¦ È®ÀÎÇϱâ À§ÇØ ´ë¿ë·® data Àü´Þ */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* -------------------------------------------------------------------- */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netinet/in.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h>
//Updated : ÆÄÀÏ°ü·Ã include¹® #include <unistd.h> #include <fcntl.h> #include <sys/uio.h> #include <sys/stat.h>
#define ServerPort 5800 #define ClientPort 5801 #define MAXSIZE 512 #define BUFFERSIZE 4096
int main(int argc, char *argv[]) { int sock, addr_len; int fd, bytes=0,numbytes, i; char buffer[BUFFERSIZE]; char RcvFromBuf[MAXSIZE]; struct sockaddr_in ServerSockAddr; /* connector's address information */ struct sockaddr_in ClientSockAddr; /* my address information */ struct in_addr *InetAddr; struct hostent *ServerInfo;
if ((ServerInfo=gethostbyname(argv[1])) == NULL){ /* get the host info */ printf("Client Error! gethostbyname() error\n"); exit(1); } //Updated : ÆÄÀÏÀ» Àб⠸ðµå·Î ¿¬´Ù(Àú¼öÁØ ÀÔÃâ·Â) if((fd=open(argv[2],O_RDONLY))<0){ printf("Cannot open the file!"); exit(1); } InetAddr=(struct in_addr *) *(ServerInfo->h_addr_list); printf("[Client] server address %s \n",inet_ntoa(*InetAddr));
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1){ printf("Client Error! socket() error\n"); exit(1); } printf("[Client] Socket created.\n");
bzero((char*) &ServerSockAddr, sizeof(ServerSockAddr)); ServerSockAddr.sin_family = AF_INET; ServerSockAddr.sin_port = htons(ServerPort); ServerSockAddr.sin_addr.s_addr = InetAddr->s_addr;
//Updated : ¼¹öÃø¿¡¼ÀÇ sendto¸¦ ¹Þ±â À§ÇØ client±¸Á¶Ã¼ ¼³Á¤ bzero((char*) &ClientSockAddr, sizeof(ClientSockAddr)); ClientSockAddr.sin_family = AF_INET; ClientSockAddr.sin_port = htons(ClientPort); ClientSockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind (sock,(struct sockaddr *)&ClientSockAddr, sizeof(struct sockaddr))) { printf("Server Error! bind() error"); exit(1); } printf("[Server] Socket binded.\n");
for(i=0; i<BUFFERSIZE; I++) buffer[i]=NULL;
//Updated : ÆÄÀÏ¿¡¼ read·Î ¹öÆÛ´ÜÀ§¸¸Å ÀÐ¾î¼ sendto·Î ¼¹öÃøÀ¸·Î º¸³»´Â while¹® while((numbytes=read(fd,buffer,BUFFERSIZE))>0){ if ((bytes=sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr *)&ServerSockAddr, sizeof(struct sockaddr))) == -1){ printf("Client Error! sendto() error"); exit(1); }
for(i=0; i<BUFFERSIZE; I++) buffer[i]=NULL; printf("sent %d bytes to %s\n",bytes,inet_ntoa(ServerSockAddr.sin_addr)); } close(fd); addr_len = sizeof(struct sockaddr);
//Updated : serverÃø¿¡¼ sendto·Î º¸³½ ¸ÞÁ¦Áö¸¦ recvfromÀ¸·Î ¹Þ´Â ±¸¹® if ((bytes=recvfrom(sock, RcvFromBuf, MAXSIZE, 0,(struct sockaddr *)&ServerSockAddr, &addr_len)) == -1){ printf("Client Error! recvfrom() error"); exit(1); } printf("%s\n",RcvFromBuf); close(sock);
printf("[Client] Client Exit.\n"); return 0; }
¨è ½ÇÇà °á°ú
server : server ÇÁ·Î±×·¥À» ½ÇÇà½ÃŲ Çϸé
netstat : data¸¦ Àü´Þ¹Þ±â À§ÇØ ´ë±âÇÏ°í Àִ ȸé
client : zicode.txt¸¦ ¸ðµÎ server·Î º¸³Â´Ù.
server : client¿¡¼´Â zipcode.txt¸¦ ¸ðµÎ º¸³ÂÀ¸³ª ÀϺθ¸ ¹ÞÀº ȸé
¨é °á°ú ºÐ¼® UDP¿¡¼ ¸Å ½ÇÇà ½Ã °á°ú°¡ Ʋ¸®¸ç dataÀÇ ¼Õ½ÇÀÌ ÀÖ´Ù. UDP¿¡¼´Â TCP¿¡¼¿Í °°Àº Á¦¾î¸¦ ÇÏÁö ¾Ê±â ¶§¹®¿¡ ½ÇÇà °á°ú¿¡¼ º¸´Â ¹Ù¿Í °°ÀÌ ¸¹Àº µ¥ÀÌÅÍÀÇ ¼Õ½ÇÀÌ ÀÖ´Ù. ¶ÇÇÑ °°Àº data(zipcode.txt)¸¦ TCP Åë½ÅÀ¸·Î º¸³¾ ¶§¿Í´Â ¾ÆÁÖ ¸¹Àº ¼Óµµ Â÷À̸¦ º¸ÀδÙ. ÀÌ ÀÌÀ¯·Î UDP´Â È帧Á¦¾î, ¿À·ùÁ¦¾î, ½ÃÄö½ºÁ¦¾î¸¦ ÇÏÁö ¾Ê°í data¸¦ º¸³»±â ¶§¹®ÀÌ´Ù.
1) CloseÇÏÁö ¾Ê¾ÒÀ» ¶§ bind error°¡ ¹ß»ýÇϴ°¡ ?
¨ç µ¿ÀÛ ¼³¸í client.c´Â ±âº»¿¹Á¦ÀÌ°í, server.c´Â close() ºÎºÐ¸¸ ÁÖ¼® ó¸®ÇÏ¿´´Ù. service port´Â 8038ÀÌ´Ù.
/* -------------------------------------------------------------------- */ /* server.c */ /* Case 6-10) : bind error´Â ¾ðÁ¦ ¹ß»ýÇϴ°¡ ? */ /* close¸¦ ÇÏÁö ¾Ê¾ÒÀ» ¶§ */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* -------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h>
#define ServicePort 8038 #define MSG "Server processed successfully according your requests."
int main() { int pid, num; int Rsock, Csock; // Socket Descriptor char ServerName[20]; // Server Domain Name int ClientAddrLen; // Client Address Length char buf[80]; // Receiving Buffer
struct sockaddr_in SockAddr; struct sockaddr_in ClientAddr; // struct sockaddr ClientAddr;
if (gethostname(ServerName, sizeof(ServerName))) { printf("Server Error! gethostname() error\n"); exit(-1); } printf("\n[Server] server name: %s\n", ServerName);
if ((Rsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Server Error! socket() error"); exit(-1); } printf("[Server] Socket created.\n");
bzero((char*) &SockAddr, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr.sin_port = htons(ServicePort);
if (bind(Rsock, (struct sockaddr *) &SockAddr, sizeof(SockAddr))) { printf("Server Error! bind() error"); exit(-1); } printf("[Server] Socket binded.\n");
if (listen(Rsock, 5)) { printf("Server Error! listen() error"); exit(-1); } printf("[Server] Socket listened.\n");
while (1) { printf("[Server] Waiting for connection request.\n\n"); ClientAddrLen = sizeof(ClientAddr); if ((Csock = accept(Rsock, (struct sockaddr *) &ClientAddr, &ClientAddrLen)) < 0) { printf("Server Error! accept() error\n"); printf("Rsock = %d Csock = %d\n", Rsock, Csock); exit(-1); } printf("[Server] Client(%s) and Server Connected.\n", inet_ntoa(ClientAddr.sin_addr)); printf("[Server] Created child process.\n"); if ((pid = fork()) < 0 ) { printf("Server Error! fork() error"); exit(-1); } else if (pid == 0) { /* Child Process */ close(Rsock); printf("[Child] Waiting for client data.\n"); if ((num = recv(Csock, buf, sizeof(buf), 0)) < 0) { printf("[Child] Receive Error!\n"); exit(-1); } printf("[Child] Data from Client(%s:%d) [%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf); send(Csock, MSG, (sizeof(MSG)), 0); printf("[Child] Sent response message to client.\n"); printf("[Child] Exit.\n");
//close(Csock); // Be Careful! exit(0); } else if (pid > 0) { /* Parent Process */ close(Csock); } } }
¨è ½ÇÇà °á°ú
server : Á¤»óÀûÀ¸·Î data¸¦ Àü´Þ¹ÞÀº ȸé
client : Á¤»óÀûÀ¸·Î data¸¦ Àü´ÞÇÑ ¸ð½À
netstat : data Àü´Þ ÈÄ ³×Æ®Œö »óÅÂ
server : CTRL + C ÈÄ ´Ù½Ã server¸¦ ½ÇÇà½ÃŲ ȸé
¨é °á°ú ºÐ¼® close()¸¦ ÇÏÁö ¾Ê´õ¶óµµ ÇÁ·Î±×·¥ÀÌ Á¾·áµÇ¸é¼ Process°¡ Á¡À¯ÇÏ°í ÀÖ´ø Port¸¦ ¹ÝȯÇϹǷΠ´Ù½Ã server programÀ» ½ÇÇà ½ÃÄѵµ bind error °¡ ¹ß»ýÇÏÁö ¾Ê´Â´Ù. ¼¹ö ÇÁ·Î±×·¥¿¡¼ close()ºÎºÐÀ» ÁÖ¼®Ã³¸® ÇÏ¿´±â ¶§¹®¿¡ client¿¡¼ ¸ÕÀú close ¿äûÀ» º¸³»°Ô µÈ´Ù. ±×·¯¹Ç·Î clientÇÁ·Î¼¼¼°¡ TIME_WAIT»óÅ¿¡ ºüÁö°Ô µÇ°í ¼¹ö ÇÁ·Î±×·¥À» ´Ù½Ã ½ÇÇà½ÃÄѵµ bind error°¡ »ý±â´Â °æ¿ì´Â ¹ß»ýÇÏÁö ¾Ê´Â´Ù.
2) exit¸¦ ÇÏÁö ¾ÊÀ» °æ¿ì bind error°¡ ¹ß»ýÇϴ°¡ ?
¨ç µ¿ÀÛ È¯°æ client.c´Â ±âº»¿¹Á¦ÀÌ°í server.c´Â exit(0) ºÎºÐ¸¸ ÁÖ¼® ó¸®ÇÏ¿© ½ÇÇàÇÑ´Ù. service port´Â 8038ÀÌ´Ù.
/* ------------------------------------------------------------------- */ /* server.c */ /* Case 6-10) : Port Binding ¹®Á¦ (TCP Socket) */ /* exit()¸¦ ÇÏÁö ¾ÊÀº °æ¿ì */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* ------------------------------------------------------------------- */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h>
#define ServicePort 8038 #define MSG "Server processed successfully according your requests."
int main() { int pid, num; int Rsock, Csock; // Socket Descriptor char ServerName[20]; // Server Domain Name int ClientAddrLen; // Client Address Length char buf[80]; // Receiving Buffer struct sockaddr_in SockAddr; struct sockaddr_in ClientAddr; // struct sockaddr ClientAddr;
if (gethostname(ServerName, sizeof(ServerName))) { printf("Server Error! gethostname() error\n"); exit(-1); } printf("\n[Server] server name: %s\n", ServerName);
if ((Rsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Server Error! socket() error"); exit(-1); } printf("[Server] Socket created.\n");
bzero((char*) &SockAddr, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr.sin_port = htons(ServicePort);
if (bind(Rsock, (struct sockaddr *) &SockAddr, sizeof(SockAddr))) { printf("Server Error! bind() error"); exit(-1); }
printf("[Server] Socket binded.\n");
if (listen(Rsock, 5)) { printf("Server Error! listen() error"); exit(-1); }
printf("[Server] Socket listened.\n");
while (1) { printf("[Server] Waiting for connection request.\n\n");
ClientAddrLen = sizeof(ClientAddr); if ((Csock = accept(Rsock, (struct sockaddr *) &ClientAddr, &ClientAddrLen)) < 0) { printf("Server Error! accept() error\n"); printf("Rsock = %d Csock = %d\n", Rsock, Csock); exit(-1); } printf("[Server] Client(%s) and Server Connected.\n", inet_ntoa(ClientAddr.sin_addr)); printf("[Server] Created child process.\n");
if ((pid = fork()) < 0 ) { printf("Server Error! fork() error"); exit(-1);
} else if (pid == 0) { /* Child Process */ close(Rsock); printf("[Child] Waiting for client data.\n"); if ((num = recv(Csock, buf, sizeof(buf), 0)) < 0) { printf("[Child] Receive Error!\n"); exit(-1); }
printf("[Child] Data from Client(%s:%d) [%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf);
send(Csock, MSG, (sizeof(MSG)), 0); printf("[Child] Sent response message to client.\n"); printf("[Child] Exit.\n"); close(Csock); // Be Careful! // exit(0);
} else if (pid > 0) { /* Parent Process */ close(Csock); } } }
¨è ½ÇÇà °á°ú
server : Á¤»óÀûÀ¸·Î ½ÇÇàÇÑ´Ù.
client : Á¤»óÀûÀ¸·Î ½ÇÇàÇÑ´Ù.
netstat : server¿Í client °£ÀÇ Á¢¼ÓÀÌ È®¸³µÇ¾ú´Ù.
server : client·ÎºÎÅÍ data¸¦ ¹Þ°í ¹Ù·Î accept error°¡ ¹ß»ýÇÑ´Ù.
server : server¸¦ Á×ÀÌ°í ´Ù½Ã ½ÇÇàÇÏÀÚ bind error°¡ ¹ß»ýÇÑ´Ù.
¨é °á°ú ºÐ¼® accept error°¡ ¹ß»ýÇÏ´Â °ÍÀº communication ¼ÒÄÏÀÌ exit¸¦ ÇÏÁö ¾Ê¾Æ Á×Áö ¾Ê°í ±×´ë·Î »ì¾ÆÀֱ⠶§¹®¿¡ ¹ß»ýÇÑ´Ù. close, exit·Î ÇÁ·Î±×·¥À» Á¾·á ½Ã¿¡¼ bind error°¡ ¹ß»ýÇÒ °¡´É¼ºÀÌ ÀÖ´Ù. serverÃø¿¡¼ TIME_WAIT »óÅ°¡ µÇ¸é bind error°¡ ¹ß»ýÇϱ⠶§¹®ÀÌ´Ù. clientÃø¿¡¼ TIME_WAIT »óÅ¿¡ ³õÀ̸é bind error´Â ³ªÁö ¾Ê´Â´Ù. ÀÌ´Â client°¡ bind¸¦ ÇÏÁö ¾Ê±â ¶§¹®ÀÌ´Ù. bind¸¦ ÇÏÁö ¾ÊÀ¸¸é Ãæµ¹ÀÌ ³ªÁö ¾Ê´Â ÀÓÀÇÀÇ Æ÷Æ®¸¦ »ç¿ëÇϱ⠶§¹®ÀÌ´Ù. Process kill, CTRL + C·Î Á¾·á ÇÒ °æ¿ì´Â bind error°¡ ³ªÁö ¾Ê´Â´Ù. ÀÌ´Â ÇÁ·Î¼¼½º°¡ °Á¦ Á¾·á ½Ã ¸ðµç ÀÚ¿øÀ» OS³ª Ä¿³ÎÀÌ °Á¦·Î »¯¾î ¹ö¸®±â ¶§¹®ÀÌ´Ù.
< Âü°í > TIME_WAIT TIME_WAIT »óÅ¿¡ ¸Ó¹«´Â ½Ã°£Àº MSL(ÃÖ´ë ¼¼±×¸ÕÆ® ¼ö¸í)ÀÇ µÎ ¹èÀÌ´Ù. ¹öŬ¸® ¼ÒÄÏ¿¡¼ÀÇ ½Ã°£Àº ÀüÅëÀûÀ¸·Î 30Ãʸ¦ »ç¿ëÇÑ´Ù. ÀÌ´Â TIME_WAIT »óÅ¿¡ ¸Ó¹«´Â ½Ã°£ÀÌ 1ºÐ¿¡¼ 4ºÐ »çÀÌÀÓÀ» ¶æÇÑ´Ù. MSLÀº ¾î´À IPÀÇ DatagramÀÌ ÀÎÅͳݿ¡ »ì¾ÆÀÖ´Â ÃÖ´ë ½Ã°£ÀÌ´Ù. ¿ì¸®°¡ ÀϹÝÀûÀ¸·Î bind error°¡ ³µÀ» ¶§ ÀÏÁ¤½Ã°£ÀÌ Áö³ª¸é ´Ù½Ã ÇÁ·Î±×·¥ÀÌ ½ÇÇàµÇ´Â ÀÌÀ¯°¡ ¹Ù·Î ÀÏÁ¤½Ã°£ÀÌ Áö³ª¸é TIME_WAIT »óÅ·ΠÇÁ·Î¼¼¼°¡ Á¡À¯ÇÏ°í ÀÖ´ø ¸®¼Ò½º¸¦ OS°¡ ¹Ýȯ ¹Þ±â ¶§¹®ÀÌ´Ù.
6-11. Server³ª Client°¡ Á×´Â °æ¿ì ?
1) ServerÀÇ child process°¡ Á×´Â °æ¿ì ?
¨ç µ¿ÀÛ È¯°æ concurrent ¹æ½ÄÀ» »ç¿ëÇÒ °ÍÀ̸ç server.c¿Í client.c´Â ¼Ò½º ¼öÁ¤ ¾øÀÌ ±âº»¿¹Á¦·Î ÁøÇàÇÑ´Ù. server port´Â 8001¹øÀÌ´Ù.
¨è ½ÇÇà °á°ú
server : server ÇÁ·Î±×·¥À» ½ÇÇàÇÏ¿´´Ù.
ps : server process°¡ È°¼ºÈµÇ¾î Àִ ȸé, parend process´Â 22885¹øÀÌ´Ù.
client : client°¡ Á¢¼ÓÇÑ´Ù.
ps : client°¡ Á¢¼Ó ÈÄ child process°¡ »ý¼ºµÇ¾ú´Ù.
ps : child process¸¦ killÇß´Ù.
client : serverÀÇ child process¸¦ killÈÄ data¸¦ º¸³Â´Ù.
ps : killµÈ child process°¡ Á»ºñ process·Î ³²¾Æ ÀÖ´Ù.
¨é °á°ú ºÐ¼® serverÀÇ child process¸¦ killÇÑ ÈÄ client¿¡¼ server·Î data¸¦ º¸³ÂÀ¸³ª ÀÀ´ä ¸Þ½ÃÁö¸¦ ¹ÞÁö ¸øÇß´Ù. ÀÌ´Â serverÀÇ child process¿Í client°¡ connectµÇ¾î ÀÖ´Â »óÅ¿´´Âµ¥ serverÂÊÀÇ process¸¦ Á×ÀÌ´Ï±î µÑ °£ÀÇ ¿¬°áÀÌ ²÷¾îÁ® ¹ö·È´Ù. killµÈ child process´Â Á»ºñ process·Î ³²¾ÆÀÖÀ¸¸ç, parent process°¡ Á×Áö ¾Ê´Â ÇÑ °è¼Ó À¯ÁöµÈ´Ù.
2) serverÀÇ parent process°¡ Á×´Â °æ¿ì
¨ç µ¿ÀÛ È¯°æ concurrent ¹æ½ÄÀ» »ç¿ëÇÒ °ÍÀ̸ç server.c¿Í client.c´Â ¼Ò½º ¼öÁ¤ ¾øÀÌ ±âº»¿¹Á¦·Î ÁøÇàÇÑ´Ù. server port´Â 8001¹øÀÌ´Ù.
¨è ½ÇÇà °á°ú
server : server ÇÁ·Î±×·¥À» ½ÇÇàÇÑ´Ù.
ps : serverÀÇ parent process¸¦ È®ÀÎÇÑ´Ù.
ps : client°¡ Á¢¼ÓÇÏ°í, server´Â child process¸¦ »ý¼ºÇß´Ù.
ps : serverÀÇ parent process¸¦ kill Çß´Ù.
server : parent process°¡ Á×Àº ÈÄ¿¡µµ child process´Â client·ÎºÎÅÍ data¸¦ Àü´Þ¹Þ¾Ò´Ù.
¨é °á°ú ºÐ¼® serverÀÇ parent process°¡ Á׾ child procss´Â client¿Í Á¤»óÀûÀ¸·Î data¸¦ ÁÖ°í¹Þ´Â´Ù. ÀÌ´Â parent proces´Â client·ÎºÎÅÍ connect¸¸ ¸¸µé¾îÁö°í data Àü´Þ°úÁ¤Àº child process¿Í ÀÌ·ç¾îÁö±â ¶§¹®ÀÌ´Ù.
3) client process°¡ Åë½Å Áß Á×´Â °æ¿ì.
¨ç µ¿ÀÛ È¯°æ data¸¦ º¸³»´Â Áß client°¡ Á×´Â °æ¿ìÀ̹ǷΠbufferÀÇ Å©±â¸¦ ´ÃÀδÙ. data°¡ Àü´ÞµÇ´Â °úÁ¤À» ȸ鿡 ³ªÅ¸³»±â À§ÇØ file openºÎºÐÀÌ ÇÊ¿äÇÏ´Ù. ¶ÇÇÑ Çѹø¸¸ recv¾Ê°í °è¼ÓÀûÀ¸·Î ¹Þ±â À§ÇØ ¼Ò½º¸¦ ¾Æ·¡¿Í °°ÀÌ server.c¿Í client.c¸¦ ¼öÁ¤ÇÑ´Ù.
/* -------------------------------------------------------------------- */ /* server.c */ /* Case 6-11) : server³ª client process¸¦ °Á¦·Î Á×ÀÏ °æ¿ì */ /* 3) µ¥ÀÌÅÍ Àü¼ÛµµÁß client°¡ Á×À» °æ¿ì ? */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* -------------------------------------------------------------------- */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h>
#define BUFFERSIZE 4096 // updated ! #define ServicePort 8001 #define MSG "Server processed successfully according your requests."
int main() { int pid, num; int Rsock, Csock; char ServerName[20]; int ClientAddrLen; char buf[BUFFERSIZE]; // updated ! struct sockaddr_in SockAddr; struct sockaddr_in ClientAddr;
if (gethostname(ServerName, sizeof(ServerName))) { printf("Server Error! gethostname() error\n"); exit(-1); } printf("\n[Server] server name: %s\n", ServerName);
if ((Rsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Server Error! socket() error"); exit(-1); } printf("[Server] Socket created.\n");
bzero((char*) &SockAddr, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); SockAddr.sin_port = htons(ServicePort);
if (bind(Rsock, (struct sockaddr *) &SockAddr, sizeof(SockAddr))) { printf("Server Error! bind() error"); exit(-1); } printf("[Server] Socket binded.\n");
if (listen(Rsock, 5)) { printf("Server Error! listen() error"); exit(-1); } printf("[Server] Socket listened.\n");
while (1) { printf("[Server] Waiting for connection request.\n\n"); ClientAddrLen = sizeof(ClientAddr); if ((Csock = accept(Rsock, (struct sockaddr *) &ClientAddr, &ClientAddrLen)) < 0) { printf("Server Error! accept() error\n"); printf("Rsock = %d Csock = %d\n", Rsock, Csock); exit(-1); } printf("[Server] Client(%s) and Server Connected.\n", inet_ntoa(ClientAddr.sin_addr)); printf("[Server] Created child process.\n"); if ((pid = fork()) < 0 ) { printf("Server Error! fork() error"); exit(-1); } else if (pid == 0) { close(Rsock); printf("[Child] Waiting for client data.\n"); /* if ((num = recv(Csock, buf, sizeof(buf), 0)) < 0) { // Updated ! printf("[Child] Receive Error!\n"); exit(-1); } printf("[Child] Data from Client(%s:%d) [%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf); */
while((num = recv(Csock, buf, sizeof(buf), 0)) > 0){ // Updated ! if(num<0){ printf("[Child] Receive Error!\n"); exit(-1); } else printf("[Child] Data from Client(%s:%d) [%s]\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf); }
send(Csock, MSG, (sizeof(MSG)), 0); printf("[Child] Sent response message to client.\n");
printf("[Child] Exit.\n"); close(Csock); exit(0); } else if (pid > 0) { close(Csock); } } }
/* --------------------------------------------------------------------- */ /* client.c */ /* Case 6-11) : server³ª client process¸¦ °Á¦·Î Á×ÀÏ °æ¿ì */ /* 3) µ¥ÀÌÅÍ Àü¼ÛµµÁß client°¡ Á×À» °æ¿ì ? */ /* ÃÖÁ¾ ¼öÁ¤ÀÏ : 2002.02.22 */ /* -------------------------------------------------------------------- */
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <string.h>
#include <unistd.h> #include <fcntl.h> #include <sys/uio.h> #include <sys/stat.h>
#define BUFFERSIZE 4096 // update ! #define MAXSIZE 512 #define ServicePort 8001
int main(int argc, char *argv[]) { int sd; int numbytes,infd,outfd,bytes,i; // update ! char buffer[BUFFERSIZE]; // update ! struct in_addr *InetAddr; struct sockaddr_in ServerSockAddr; struct hostent *ServerInfo; char SndBuf[MAXSIZE], RcvBuf[MAXSIZE];
if ((ServerInfo = gethostbyname(argv[1])) == NULL) { printf("Client Error! gethostbyname() error\n"); exit(-1); } InetAddr = (struct in_addr *) *(ServerInfo->h_addr_list); printf("[Client] sever address %s \n", inet_ntoa(*InetAddr));
if ((infd=open(argv[2],O_RDONLY))<0){ // update ! printf("File not open Error!"); exit(1); }
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { printf("Client Error! socket() error \n"); exit(-1); } printf("[Client] Socket created.\n");
bzero((char*) &ServerSockAddr, sizeof(ServerSockAddr)); ServerSockAddr.sin_family = AF_INET; ServerSockAddr.sin_addr.s_addr = InetAddr->s_addr; ServerSockAddr.sin_port = htons(ServicePort);
printf("[Client] Clint sent connection request.\n"); if (connect(sd, (struct sockaddr *) &ServerSockAddr, sizeof(ServerSockAddr)) < 0) { printf("Client Error! connect() error\n"); exit(-1); } printf("[Client] Clint and server connected.\n");
/* printf("[Client] Input Data ? "); // update ! gets(SndBuf);
send(sd, SndBuf, (sizeof(SndBuf)), 0); printf("[Client] Client sent Data.\n");
recv(sd, RcvBuf, (sizeof(RcvBuf)), 0); printf("[Client] Client received Data.\n");
printf("[Client] Data from Server [%s]\n", RcvBuf); */
while((bytes=read(infd,buffer,BUFFERSIZE))>0){ // update ! send(sd,buffer,(sizeof(buffer)),0); printf("sent %d bytes to %s\n",bytes,inet_ntoa(ServerSockAddr.sin_addr)); }
close(infd); // update ! close(outfd); // update ! close(sd); printf("[Client] Client Exit.\n"); }
¨è ½ÇÇà °á°ú
server : server ÇÁ·Î±×·¥À» ½ÇÇàÇÑ´Ù.
ps : serverÀÇ parent process¸¦ È®ÀÎÇÑ´Ù.
client : zipcode.txt¶ó´Â 1.8MByte data¸¦ Àü¼ÛÇÑ´Ù.
ps : server·Î data¸¦ Àü¼ÛÇÏ´Â µ¿¾È process »óÅ ǥ½Ã
ps : server·Î data¸¦ Àü¼ÛÇÏ´Â µ¿¾È client process¸¦ kill Çß´Ù.
client : killÇÏ´Â ¼ø°£ data Àü´ÞÀÌ ²÷°å´Ù.
¨é °á°ú ºÐ¼® server·Î data¸¦ Àü´ÞÇÏ´Â client¸¦ °Á¦·Î killÇÒ °æ¿ì À§¿Í °°ÀÌ killÇÑ ¼ø°£ data Àü´ÞÀÌ ²÷°ÜÁø´Ù.
6-12. Ç¥ÁØ ÀÎÅÍ³Ý µî·Ï ¼ºñ½º
1) ¼Ò½º ÆÄÀÏ Ã·ºÎ.
/*******************************************************************************/ /* ECHOC.C */ /* Ç¥ÁØ ÀÎÅÍ³Ý µî·Ï ¼ºñ½º */ /*******************************************************************************/
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <string.h>
#define MAXLINE 512
int main(int argc, char *argv[]) { int sd; struct in_addr *ptr1; struct sockaddr_in server; char buf[80] ; char sendline[MAXLINE], recvline[MAXLINE+1]; struct hostent *host; struct servent *serv;
FILE *fp;
if ((host = gethostbyname(argv[1])) == NULL) { printf("server-side : error gethostbyname\n"); exit(1); } else ptr1 = (struct in_addr *) *(host->h_addr_list);
if ((serv = getservbyname("echoex", "tcp"))== NULL) { printf("server : getservbyname error"); exit(2); } else printf("\nechoex server port : %d\n", serv->s_port); bzero((char*)&server, sizeof(server)); server.sin_family = AF_INET; server.sin_addr.s_addr = ptr1->s_addr; server.sin_port = htons(serv->s_port);
if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) printf("client:socket error \n");
printf("sever address %s \n", inet_ntoa(*ptr1));
if(connect(sd, (struct sockaddr *)&server, sizeof(server))< 0) printf("client:bind error \n");
gets(sendline);
send(sd, sendline, (sizeof(sendline)),0); recv(sd, recvline, (sizeof(recvline)),0);
printf(" recv : %s \n",recvline);
close(sd); exit(0); }
/*******************************************************************************/ /* ECHOCD.C */ /* Ç¥ÁØ ÀÎÅÍ³Ý µî·Ï ¼ºñ½º */ /*******************************************************************************/
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h>
#define MS "Server processed successfully." #define MS1 "Server cannot process due to fork error."
main() { int rs, cs, fromlen, childpid, num ; char name[20], buf[80]; struct sockaddr_in sin; struct sockaddr from; struct hostent *host; struct servent *serv;
fromlen = sizeof(struct sockaddr);
if (gethostname(name, sizeof(name))) printf("server: gethostname error"); else printf("\nserver name : %s\n", name);
if ((host = gethostbyname(name)) == NULL) printf("server : gethostbyname error");
if ((serv = getservbyname("echoex", "tcp"))== NULL ) printf("server : getservbyname error"); else printf("\nechoex server port : %d\n", serv->s_port);
bzero((char*)&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(serv->s_port);
if ((rs = socket(AF_INET, SOCK_STREAM, 0)) == -1) printf("server: socket error");
if (bind(rs, (struct sockaddr *)&sin, sizeof(sin))) printf("server: bind error");
if (listen(rs, 5)) printf("server: listen error");
for (;;) { cs = accept(rs, &from, &fromlen);
if (cs < 0) printf("server: accept error");
if ((childpid = fork()) < 0 ) { printf("server: fork error"); send(cs, MS1, (sizeof(MS1)), 0); } else if (childpid == 0 ) { close(rs); num = recv(cs, buf, sizeof(buf), 0); buf[num-1] = 0x00;
printf("server received [%s]\n", buf);
send(cs, MS, (sizeof(MS)), 0); exit( 0 ); } close (cs); } } |