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ÀÇ Á¤º¸¸¦ °¡Áö°í ¼­·ÎÀÇ Åë½Å·Î¸¦ È®¸³ÇØ ÁÖ´Â ÀÏÀ» Çϱ⠶§¹®ÀÌ´Ù.


     6-6. Blocking Operation¿¡ ´ëÇÏ¿© ¾Ë¾Æº¸ÀÚ(TCP).

 

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¸¦ º¸³»±â ¶§¹®ÀÌ´Ù.



     6-10. Bind Error´Â ¾ðÁ¦ ¹ß»ýÇϴ°¡?

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);

}

}