ÇÔ¼ö Æ÷ÀÎÅÍ·Î ±¸ÇöÇÏ´Â Àü¼ú ÆÐÅÏ
ÃÑ ÆäÀÌÁö ¼ö : 3224

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



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

Contents

1 ÇÔ¼ö Æ÷ÀÎÅÍ·Î ±¸ÇöÇÏ´Â Àü¼ú ÆÐÅÏ
1.1 ¼Ò°³
1.2 Àü¼ú ÆÐÅÏ ÀÀ¿ë
1.3 Àü¼ú ÆÐÅÏÀ» ÀÌ¿ëÇÑ °£°áÇÑ ÄÚµå »ý¼º
1.4 ÆÄÀÏ Àü¼Û ÇÁ·Î±×·¥ ¸¸µé±â
1.5 Åë½Å ÇÁ·ÎÅäÄÝ
1.6 ¼­¹ö ÇÁ·Î±×·¥ ÀÛ¼º
2 °ü·Ã ¹®¼­
3 È÷½ºÅ丮

1 ÇÔ¼ö Æ÷ÀÎÅÍ·Î ±¸ÇöÇÏ´Â Àü¼ú ÆÐÅÏ

1.1 ¼Ò°³

ÇÔ¼ö Æ÷ÀÎÅ͸¦ ÀÌ¿ëÇÑ Àü¼ú ÆÐÅÏÀÇ ±¸ÇöÀÔ´Ï´Ù. 2004³â¿¡ ¸¸µç ¹®¼­Àε¥, »ý°¢³­±è¿¡ ³»¿ëÀ» ¼öÁ¤/º¸¿ÏÇß½À´Ï´Ù. ÇÔ¼öÆ÷ÀÎÅÍ¿¡ ´ëÇÑ ÀϹÝÀûÀÎ ³»¿ëÀº ÇÔ¼ö Æ÷ÀÎÅÍÀÇ »ç¿ë¹®¼­¸¦ Âü°íÇϽñ⠹ٶø´Ï´Ù.

ÀÌ ¹®¼­´Â ÇÔ¼ö Æ÷ÀÎÅÍÀÇ ÀÀ¿ëÀÔ´Ï´Ù.

1.2 Àü¼ú ÆÐÅÏ ÀÀ¿ë

Àü¼ú ÆÐÅÏÀº ½ÇÇà½Ã°£¿¡ ¾Ë°í¸®ÁòÀ» ¼±ÅÃÇϱâ À§ÇÑ ¸ñÀûÀ¸·Î »ç¿ëÇÕ´Ï´Ù. Á¤Ã¥À» ÄÚµåÈ­ ÇÑ ´ÙÀ½, ¼±ÅÃÇÒ ¼ö ÀÖ°Ô ÇÑ´Ù´Â Àǹ̿¡¼­ policy patternÀ̶ó°í ºÎ¸£±âµµ ÇÕ´Ï´Ù. ÀÌ ÆÐÅÏÀº ¾Ë°í¸®Áò ±ºÀ» Á¤ÀÇÇÑ´ÙÀ½ À̵éÀ» ĸ½¶È­Çϰí ÄÚµå»ó¿¡¼­ Çʿ信 µû¶ó¼­ ¼±ÅÃÇϵµ·Ï ÇÕ´Ï´Ù. ÀÌ ÆÐÅÏÀ» ÀÌ¿ëÇØ¼­ ¸¸µé¾îÁø ÄÚµå´Â ¼Ò½ºÄÚµåÀÇ º¯°æ ¾øÀÌ ¾Ë°í¸®ÁòÀ» Ãß°¡ÇÒ ¼ö ÀÖ°Ô µË´Ï´Ù.

ÇÔ¼ö Æ÷ÀÎÅ͸¦ Àü¼ú ÆÐÅÏ¿¡ ÀÀ¿ëÇϱâ À§Çؼ­, ÇÁ·Î±×·¥À» Á÷Á¢ ¸¸µé¾î º¸±â·Î Çß½À´Ï´Ù. ÀÌ ÇÁ·Î±×·¥Àº »ç¿ëÀÚÀÇ ¿äûÀ» Àо ó¸®ÇÏ´Â ÇÁ·Î±×·¥ÀÔ´Ï´Ù. HTTP ¼­¹ö ÇÁ·Î±×·¥°ú ºñ½ÁÇÏ´Ù°í º¸½Ã¸é µÇ°Ú½À´Ï´Ù.

¼­¹ö´Â »ç¿ëÀÚÀÇ ´Ù¾çÇÑ ¿äûÀ» ºÐ·ùÇÏ°í ±×¿¡ ¸Â´Â ¾Ë°í¸®ÁòÀ» ¼±ÅÃÇØ¼­ ÀÛ¾÷À» ÇØ¾ß ÇÕ´Ï´Ù. °¡Àå ÀϹÝÀûÀÎ ¹æ¹ýÀº if else, case¹®À» »ç¿ëÇÏ´Â °Ì´Ï´Ù. Á¶°Ç ¹®À» ÀÌ¿ëÇØ¼­ ¾Ë°í¸®ÁòÀ» ¼±ÅÃÇÏ´Â °ÅÁÒ. ÀÌ ¹æ¹ýÀº ´Ü¼øÇϰí ÀÌÇØÇϱ⠽±±ä ÇÏÁö¸¸, »õ·Î¿î Äڵ尡 Ãß°¡µÉ ¶§¸¶´Ù ¸ÞÀÎ ¼Ò½ºÄڵ忡 Á÷Á¢ ºÐ±â¹®À» ´Ã·Á¾ß ÇÑ´Ù´Â ´ÜÁ¡ÀÌ ÀÖ½À´Ï´Ù.

´ÙÀ½ °°Àº °æ¿ìÁÒ
Ŭ¶óÀ̾ðÆ®ÀÇ ÇÁ·ÎÅäÄÝ ¸Þ½ÃÁö¸¦ ºÐ¼®ÇÑ´Ù. 
if (·Î±×ÀÎ ¿äû À̶ó¸é) 
{ 
  DB¿¡ ¿¬°áÇØ¼­ ÀÌ·± Àú·± ÀÛ¾÷..   
} 
else if (»ç¿ëÀÚ Á¤º¸ ¿äûÀ̶ó¸é) 
{ 
  ·Î±×ÀÎ µÇ¾ú´ÂÁö ¿©ºÎ È®ÀÎÈÄ DB¿¡ ¿¬°áÇØ¼­.. 
} 
else if (»ç¿ëÀÚ Á¤º¸ º¯°æ¿äû) 
{ 
  ... 
} 
else if (...) 
{ 
  ... 
} 
.... 
 
º¸±â¿¡µµ Èûµé°í, º¹ÀâÇÏ°í ¹º°¡ Àϰü¼ºÀÌ ¾ø¾î º¸ÀÔ´Ï´Ù. À¯Áö/ º¸¼ö¼ºµµ ÁÁÁö ¾Ê°í¿ä. ÀÌ Äڵ带 ¹Ù²ãº¸·Á°í ÇÕ´Ï´Ù.

1.3 Àü¼ú ÆÐÅÏÀ» ÀÌ¿ëÇÑ °£°áÇÑ ÄÚµå »ý¼º

¾ÆÀ̵ð¾î´Â °£´ÜÇÕ´Ï´Ù. À¯ÀúÀÇ ¿äû ¹®ÀÚ¿­À» Ű·ÎÇÏ´Â mapÀ» ¸¸µé°í, °ªÀ¸·Î´Â ÇØ´ç ¹®ÀÚ¿­À» ó¸®Çϱâ À§ÇÑ ÇÔ¼öÀÇ Æ÷ÀÎÅ͸¦ µî·ÏÇÏ´Â °Ì´Ï´Ù. ¿¹¸¦ µé¾î À¯Àú°¡ "Helo"¶ó´Â ¿äûÀ» Çß´Ù¸é FuncHelo ÇÔ¼ö¸¦ È£ÃâÇÏ´Â ½ÄÀÔ´Ï´Ù.

±×·¯±â À§Çؼ­´Â ÃÖÃÊ¿¡ ÇÁ·ÎÅäÄÝ ¹®ÀÚ¿­ À̸§°ú °ü·ÃµÈ ÇÔ¼öÆ÷ÀÎÅ͸¦ µî·ÏÇÏ´Â ·çƾ Áï command mapÀ» ¸¸µå´Â ·çƾ, ³ªÁß¿¡ ¹®ÀÚ¿­·Î °Ë»öÇØ¼­ ÇÔ¼öÆ÷ÀÎÅ͸¦ µ¹·ÁÁÖ´Â ·çƾÀÌ ÇÊ¿äÇÒ °Ì´Ï´Ù. ÀڷᱸÁ¶¸¦ ¸¸µé±â°¡ ±ÍÂúÀº Àú´Â STLÀÇ mapÀ» ÀÌ¿ëÇϱâ·Î Çß½À´Ï´Ù.

Àú´Â ÆÄÀÏ ´Ù¿î·Îµå ¼­ºñ½º¸¦ ÇÏ´Â ¼­¹ö ÇÁ·Î±×·¥À» ¸¸µé·Á°í ÇÕ´Ï´Ù. À̰æ¿ì¿¡ ÃÖ¼ÒÇÑ "login", "list", "down", "quit" ÀÇ ÇÁ·ÎÅäÄÝÀÌ ÇÊ¿ä ÇÒ °Ì´Ï´Ù. ´ÙÀ½°ú °°Àº ÀڷᱸÁ¶¸¦ ¸¸µé¾î¼­ µî·ÏÇϱâ·Î Çß½À´Ï´Ù.

typedef map<string, void *(*)(void *, class FuncArg *)> ProcessingMap;  
int ProtocolFuncRegist() 
{ 
  // ÇÔ¼öÆ÷ÀÎÅ͸¦ µî·ÏÇÑ´Ù. 
  ProcessingMap["login"] = ProcessLogin; 
  ProcessingMap["list"] = ProcessList; 
  ProcessingMap["down"]    = ProcessDown; 
} 
 
void *ProcessLogin(void *data, class FuncArg *aFuncArg) 
{ 
  // ¾ÆÀ̵𸦠ÀÌ¿ëÇØ¼­ À¯È¿ÇÑ À¯ÀúÀÎÁö¸¦ °Ë»çÇÑ´Ù.     
} 
 
void *ProcessList(void *data, class FuncArg *aFuncArg) 
{ 
  // ÆÄÀÏÀÇ ¸®½ºÆ®¸¦ º¸¿©ÁØ´Ù. 
} 
 
void *ProcessDown(void *data, class FuncArg *aFuncArg) 
{ 
  // ÆÄÀÏÀ» Àü¼ÛÇÑ´Ù.  
} 
 
void *ProcessQuit(void *data, class FuncArg *aFuncArg) 
{ 
  // Á¾·áÇÑ´Ù. 
} 
 

Æ÷ÀÎÅÍ·Î Àü´ÞµÉ ÇÔ¼ö´Â µÎ°³ÀÇ ¸Å°³ º¯¼ö¸¦ °¡Áö°í ÀÖ½À´Ï´Ù. ù¹øÂ° ¸Å°³ º¯¼ö´Â Ŭ¶óÀ̾ðÆ®ÀÇ ¿äû ¹®ÀÚ¿­À̰í, µÎ¹øÂ° ¸Å°³ º¯¼ö´Â ¼¼¼Ç Á¤º¸¸¦ ´ã°í Àִ Ŭ·¡½ºÀÔ´Ï´Ù. µ¥ÀÌÅͺ£À̽º³ª ÆÄÀÏÀ» ¿­¾úÀ»°æ¿ì µ¥ÀÌÅÍ º£À̽º Æ÷ÀÎÅͳª ÆÄÀÏ Æ÷ÀÎÅ͸¦ Àü´ÞÇϱâ À§ÇÑ ¸ñÀûÀ¸·Î »ç¿ëÇÒ °Ì´Ï´Ù. ȤÀº ÇØ´ç Ŭ¶óÀ̾ðÆ®ÀÇ »óÅÂ, ·Î±×ÀÎÀ» ³¡¸¶Ä£ À¯ÀúÀÎÁö, ±ÇÇÑÀÌ ÀÖ´Â À¯ÀúÀÎÁöµî¿¡ ´ëÇÑ ºÎ°¡ÀûÀÎ Á¤º¸¸¦ ³Ñ±â±â À§Çؼ­ »ç¿ëÇÒ ¼öµµ ÀÖÀ» °Ì´Ï´Ù.

1.4 ÆÄÀÏ Àü¼Û ÇÁ·Î±×·¥ ¸¸µé±â

¸¸µé°íÀÚ ÇÏ´Â ÇÁ·Î±×·¥Àº ÆÄÀÏÀ» Àü¼ÛÇÏ´Â °£´ÜÇÑ ÇÁ·Î±×·¥À¸·Î ·Î±×ÀΰúÁ¤À» °ÅÄ¡¸é, ÆÄÀϸ®½ºÆ®¸¦ È®ÀÎÇÏ°í ¿øÇÏ´Â ÆÄÀÏÀ» ´Ù¿î·Îµå ÇÕ´Ï´Ù.

±×·¯³ª!! ÀÌ·¯ÇÑ ¸ðµç Äڵ带 ½ÇÁ¦·Î ±¸ÇöÇÏÁö ¾ÊÀ» °Ì´Ï´Ù. ÇÔ¼öÆ÷ÀÎÅÍ ÀÀ¿ë ¹æ¹ýÀ» ´Ù·ç´Â °ÍÀ̹ǷΠ¿©±â¿¡¸¸ ÁýÁßÇÒ °Ì´Ï´Ù. ½ÇÁ¦ ÆÄÀÏÀ» ´Ù¿î·Îµå ¹Þ°í, ¸®½ºÆ®¸¦ ´øÁ®ÁÖ´Â ½ÇÁ¦ ÄÚµå´Â ¸¸µéÁö ¾Êµµ·Ï ÇÒ°ÍÀÌ´Ù. eotls ¸Þ½ÃÁö¸¸ »Ñ·ÁÁÖ´Â ²®µ¥±â ÄÚµå·Î ´ëüÇÏ·ÁÇÕ´Ï´Ù.

1.5 Åë½Å ÇÁ·ÎÅäÄÝ

´ÙÀ½°ú °°ÀÌ Çì´õ + ¹Ùµð·Î ±¸¼ºÇÑ ÃÊ °£´Ü ÇÁ·ÎÅäÄÝÀ» »ç¿ëÇÒ °Ì´Ï´Ù.
struct ProtocolHeader 
{ 
    int size;      // µ¥ÀÌÅÍ »çÀÌÁî sizeof(int) + sizeof(int) + size(data)  
    char data[];   // ½ÇÁ¦ µ¥ÀÌÅÍ 
    void H2N() 
    { 
        size = htonl(size); 
        status = htonl(status); 
    } 
    void N2H() 
    { 
        size = ntohl(size); 
        status = ntohl(status); 
    } 
} 
 
  |<-------- Size ---------->| 
  +----+---------------- 
  |SIZE| DATA .... 
  +----+---------------- 
 


1.6 ¼­¹ö ÇÁ·Î±×·¥ ÀÛ¼º

¼­¹ö ÇÁ·Î±×·¥Àº RealTimeSignalÀ» ÀÌ¿ëÇØ¼­ ´ÙÁßÀÇ Å¬¶óÀÌ¾ðÆ®¸¦ ó¸®Çϵµ·Ï ÇÒ °Ì´Ï´Ù.

ÇÔ¼öÆ÷ÀÎÅ͸¦ ¸Ê¿¡ µî·Ï½ÃŰ´Â °Í ¿Ü¿¡´Â ÀϹÝÀûÀÎ ³×Æ®¿öÅ© ÇÁ·Î±×·¥°ú µ¿ÀÏÇÕ´Ï´Ù. À̿ܿ¡ Ãß°¡½ÃÄѾßÇÒ°Ô ÀÖ´Ù¸é Ŭ¶óÀ̾ðÆ®ÀÇ ¿¬°áÁ¤º¸¿Í ¾²·¹µå Ç® °ü¸®¸¦ À§ÇÑ ÀڷᱸÁ¶Á¤µµ°¡ µÉ °Ì´Ï´Ù ÇØ´ç Ŭ¶óÀÌ¾ðÆ®°¡ ¿¬°áÀ» Çß´ÂÁö, ¿¬°áÀ» Çß´Ù¸é ·Î±×ÀÎÀ» ¸¶Ä£ »óÅÂÀÎÁö µîÀÇ Á¤º¸¸¦ À¯ÁöÇÒ Çʿ䰡 Àֱ⠶§¹®ÀÌ´Ù. ¾²·¹µå Ç® ÀڷᱸÁ¶´Â, ¾²·¹µå Ç®¿¡ µî·ÏµÇ¾î ÀÖ´Â ¾²·¹µå°¡ ÇöÀç ¸î°³ÀÇ Å¬¶óÀÌ¾ðÆ®¸¦ ó¸®ÇÏ´ÂÁöÀÇ ÀڷḦ À¯ÁöÇØ¼­ °¡Àå ÀûÀº Ŭ¶óÀÌ¾ðÆ®¸¦ ó¸®ÇÏ´Â ¾²·¹µå¿¡°Ô »õ·Î µî·ÏµÈ(accept)Ŭ¶óÀÌ¾ðÆ®¸¦ ÇÒ´çÇϱâ À§ÇÑ ¸ñÀûÀ¸·Î »ç¿ëÇÕ´Ï´Ù.

RTS¿Í ¾²·¹µåÇ®, ÇÔ¼öÆ÷ÀÎÅÍ¿¡ ´ëÇÑ ¸î°³ÀÇ ¼Ò°³µÈ ±ÛÀ» ºÃ´Ù¸é ¼Ò½º¿¡ ´ëÇÑ ÀÌÇØ´Â ÁÖ¼®¸¸À¸·Î ÃæºÐÇÒ °Ì´Ï´Ù. Á¦½ÃµÇ´Â ÄÚµå´Â ±âº»ÀûÀÎ ±â´É¸¸À» ¼öÇàÇϴµ¥ ÁßÁ¡À» µÎ°í ¸¸µé¾ú½À´Ï´Ù. È¿À²¼º, ¾Æ¸§´Ù¿òµîÀº ±â´ëÇÏÁö ¸¶¼¼¿ä.

#ifndef __USE_GNU 
#define __USE_GNU 
#endif 
 
#include <signal.h> 
#include <fcntl.h> 
 
#include <sys/socket.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
 
#include <netinet/in.h> 
#include <arpa/inet.h> 
 
#include <iostream> 
 
#include <map> 
#include <vector> 
 
#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 
#define MAXDATALENTH    512 
 
 
using namespace std; 
 
int gpid; 
 
// Ŭ¶óÀÌ¾ðÆ® µ¥ÀÌÅÍ Á¤º¸ ±¸Á¶Ã¼ 
struct clidata 
{ 
  int sockfd;            // ó¸®ÇÒ ¼ÒÄÏ ¹øÈ£ 
  int signum;            // ó¸®ÇÒ RTS¹øÈ£ÀÌÀÚ Ã³¸®ÇÒ ¾²·¹µåÀÇ ID 
  char cbuf[512];        // ó¸®ÇؾßÇÒ µ¥ÀÌÅÍ     
 
  // ¾Æ·¡·Î´Â ¾²ÀÌÁö ¾Ê´Â´Ù. 
  // ÇÁ·Î±×·¥ÀÌ ÇØ¾ßÇÏ´Â ÀÏ¿¡ µû¶ó¼­ ´Ù¾çÇÑ º¯¼ö¸¦ ¼±¾ðÇØ¼­ 
  // »ç¿ëÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù. 
  int status; 
  int uid; 
  char regdate[36]; 
  char serviceinfo[256]; 
  char ip[36]; 
  char port[8]; 
}; 
 
map<int, struct clidata> ClientList;    // ó¸®ÇÒ Å¬¶óÀÌ¾ðÆ® µ¥ÀÌŸ Á¤º¸  
map<int, struct clidata>::iterator CLi; 
 
// ÇÔ¼öÆ÷ÀÎÅÍ È£Ãâ½Ã ³Ñ°ÜÁÙ µ¥ÀÌÅÍ Å¬·¡½º 
// ¿ª½Ã ÇÁ·Î±×·¥ÀÌ ÇÏ´ÂÀÏ¿¡ µû¶ó¼­ ´Ù¾çÇÏ°Ô ¼±¾ðÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù.  
class FuncArg 
{ 
  private: 
    int status; 
  public: 
}; 
 
 
typedef struct _fd_sig 
{ 
    int signum; 
    int pid; 
    int uid; 
} FdPerSignum; 
 
pthread_mutex_t MutexLock = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t  SyncCond  = PTHREAD_COND_INITIALIZER; 
 
// ¾²·¹µå Ç®°ü¸®¸¦ À§ÇÑ map ÀڷᱸÁ¶ 
multimap<int, FdPerSignum> PollMap; 
multimap<int, FdPerSignum>::iterator PollMapi; 
 
// ÇÁ·ÎÅäÄÝ¿¡ ´ëÇØ¼­ È£ÃâµÉ ÇÔ¼öÆ÷ÀÎÅ͸¦ Æ÷ÇÔÇÒ map  
typedef map<string, void *(*)(void *, class FuncArg *)> __ProcessingMap; 
__ProcessingMap ProcessingMap; 
__ProcessingMap::iterator ProcessingFunci; 
 
// login ¹®ÀÚ¿­À» ¸¸³µÀ» ¶§ È£ÃâÇÒ ÇÔ¼ö 
void *ProcessLogin(void *data, class FuncArg *aFuncArg) 
{ 
  struct clidata lclidata; 
  lclidata = *(struct clidata *)data; 
  printf("Read socket(%d) : LoginProcess : %s\n", lclidata.sockfd,  
    lclidata.cbuf); 
} 
 
// list ¹®ÀÚ¿­À» ¸¸³µÀ» ¶§ È£ÃâÇÒ ÇÔ¼ö 
void *ProcessList(void *data, class FuncArg *aFuncArg) 
{ 
  struct clidata lclidata; 
  lclidata = *(struct clidata *)data; 
  printf("Read socket(%d) : ListProcess : %s\n", lclidata.sockfd, 
     lclidata.cbuf); 
} 
 
// down ¹®ÀÚ¿­À» ¸¸³µÀ» ¶§ È£ÃâÇÒ ÇÔ¼ö 
void *ProcessDown(void *data, class FuncArg *aFuncArg) 
{ 
  struct clidata lclidata; 
  lclidata = *(struct clidata *)data; 
  printf("Read socket(%d) : DownProcess : %s\n", lclidata.sockfd, 
    lclidata.cbuf); 
} 
 
// quit ¹®ÀÚ¿­À» ¸¸³µÀ» ¶§ È£ÃâÇÒ ÇÔ¼ö 
// ¼ÒÄÏÀ» Á¾·áÇÑ´Ù.  
void *ProcessQuit(void *data, class FuncArg *aFuncArg) 
{ 
  struct clidata lclidata; 
  lclidata = *(struct clidata *)data; 
  printf("Read socket(%d) : QuitProcess : %s\n", lclidata.sockfd, 
    lclidata.cbuf); 
  close(lclidata.sockfd); 
} 
 
// ÆÄÀÏÁöÁ¤ÀÚ°¡ ¸®¾óŸÀÓ ½Ã±×³Î¿¡ ´ëÀÀÇϵµ·Ï ¼³Á¤ÇÑ´Ù. 
int setup_sigio(int fd, int sig_num, int pid) 
{ 
  if(fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC) < 0) 
  { 
    printf("setup nonblocking error:%d\n", fd); 
  } 
 
  if(fcntl(fd, F_SETSIG, SIGRTMIN+sig_num) < 0) 
  { 
    printf("Couldn't set signal %d on %d\n", SIGRTMIN, fd); 
    return -1; 
  } 
 
  if(fcntl(fd, F_SETOWN, pid) < 0) 
  { 
    printf("Couldn't set owner %d on %d\n", pid, fd); 
    return -1; 
  } 
  return 0; 
} 
 
// Ŭ¶óÀÌ¾ðÆ®·Î ºÎÅÍ ÀоîµéÀÎ µ¥ÀÌÅ͸¦ ó¸®ÇÒ ¾²·¹µå ÇÔ¼ö 
void * CliDataProcessing(void *rts_num) 
{ 
  int signum = *((int *)rts_num); 
  socklen_t socklen; 
  char buf[MAXDATALENTH]; 
  class FuncArg FArg; 
 
  struct sockaddr_in sockaddr; 
  struct siginfo sinfo; 
 
  FdPerSignum fdpersignum; 
 
  int clientnum; 
  int ret; 
  int readlen; 
  int datalen; 
 
  sigset_t sigset; 
 
  gpid = getpid(); 
  sigemptyset(&sigset); 
  sigaddset(&sigset, SIGRTMIN+signum); 
  sigprocmask(SIG_BLOCK, &sigset, NULL); 
 
  pthread_mutex_lock(&MutexLock); 
  usleep(500); 
  pthread_cond_signal(&SyncCond); 
  pthread_mutex_unlock(&MutexLock); 
 
  sigemptyset(&sigset); 
  sigaddset(&sigset, SIGRTMIN+signum); 
  sigprocmask(SIG_BLOCK, &sigset, NULL); 
  while(1) 
  { 
    struct clidata lclidata; 
    socklen = sizeof(sockaddr); 
 
    // ¾²·¹µå°¡ ó¸®Çϱâ·Î ÁöÁ¤µÈ ¼ÒÄÏ¿¡¼­ ¸®¾óŸÀÓ ½Ã±×³ÎÀÌ ¹ß»ýÇÏ´Â°É ±â´Ù¸°´Ù. 
    ret = sigwaitinfo(&sigset, &sinfo); 
    if (ret == (SIGRTMIN + signum)) 
    { 
      // ¹ÞÀ» µ¥ÀÌÅÍ Å©±â¸¦ Àоî¿Â´Ù 
      if ((readlen = read(sinfo.si_fd, (void *)&datalen, sizeof(int))) <= 0) 
      { 
        // ¸¸¾à µ¥ÀÌÅ͸¦ Àд µµÁß ¿¡·¯°¡ ¹ß»ýÇß´Ù¸é,  
        // ¼ÒÄÏÀ» ´Ý°í 
        // ¾²·¹µåÇ®ÀÇ °ªÀ» ÀçÁ¶Á¤ÇÑ´Ù. 
        PollMapi = PollMap.begin(); 
        while(PollMapi != PollMap.end()) 
        { 
          if(PollMapi->second.signum == signum) 
          { 
            fdpersignum = PollMapi->second; 
            if (PollMapi->first > 0) 
              clientnum = PollMapi->first - 1; 
            PollMap.erase(PollMapi); 
            PollMap.insert(pair<int, FdPerSignum>(clientnum, fdpersignum)); 
          } 
          PollMapi++; 
        } 
        close(sinfo.si_fd); 
      } 
      else 
      { 
        // Ŭ¶óÀÌ¾ðÆ®·Î ºÎÅÍ µ¥ÀÌÅ͸¦ Àоî¿Â´Ù. 
        void *(*Func)(void *, class FuncArg *); 
        int readn; 
        memset(buf, 0x00, MAXDATALENTH); 
        readn = read(sinfo.si_fd, buf, datalen+4); 
        memset(lclidata.cbuf, 0x00, sizeof(lclidata.cbuf)); 
        memcpy(lclidata.cbuf, buf, datalen); 
 
        if ((CLi = ClientList.find(sinfo.si_fd)) == ClientList.end()) 
        { 
          lclidata.sockfd = sinfo.si_fd; 
          lclidata.signum = signum; 
          lclidata.status = 0; 
            ClientList[sinfo.si_fd] = lclidata; 
        } 
 
        // ó¸®ÇؾßÇÒ ¸Þ½ÃÁö¿¡ ´ëÇÑ ÇÔ¼ö°¡ Á¸ÀçÇÒ ¶§ 
        // ÇØ´ç ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. 
        ProcessingFunci = ProcessingMap.find(buf); 
        if (ProcessingFunci != ProcessingMap.end()) 
        { 
          cout << "Search Function data " << endl;  
          Func = ProcessingFunci->second; 
          Func((void *)&lclidata, &FArg); 
        } 
        else 
        { 
          fprintf(stderr,"Unknown msg protocol : %s\n", buf); 
        } 
      } 
    } 
  } 
} 
 
void * socket_acceptor(void *argdata) 
{ 
  int server_sockfd, cli_sockfd; 
  int clientnum; 
  FdPerSignum fdpersignum; 
  socklen_t socklen; 
 
  sigset_t sigset; 
  struct sockaddr_in serveraddr, clientaddr; 
  struct siginfo sinfo; 
 
  int signum = *((int *)argdata); 
 
  if((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
  { 
    perror("socket error ");  
  } 
  bzero(&serveraddr, sizeof(serveraddr)); 
  serveraddr.sin_family = AF_INET; 
  serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); 
  serveraddr.sin_port = htons(5555); 
 
  if (bind (server_sockfd, (struct sockaddr *)&serveraddr, 
    sizeof(serveraddr)) == -1) 
  { 
    perror("bind error"); 
  } 
 
  if(listen(server_sockfd, 5) == -1) 
  { 
    perror("listen error"); 
  } 
 
  if(setup_sigio(server_sockfd, signum, getpid()) == -1) 
  { 
    fprintf(stderr, "sigio setting error\n"); 
  } 
 
  gpid = getpid(); 
  sigemptyset(&sigset); 
  sigaddset(&sigset, SIGRTMIN+signum); 
  sigprocmask(SIG_BLOCK, &sigset, NULL); 
 
  pthread_mutex_lock(&MutexLock); 
  usleep(500); 
  pthread_cond_signal(&SyncCond); 
  pthread_mutex_unlock(&MutexLock); 
 
  while(1) 
  { 
    int ret; 
    printf("Wait I/O Event (%d)\n", signum); 
    ret = sigwaitinfo(&sigset, &sinfo); 
    printf("IO Event OK\n"); 
    if (ret == SIGRTMIN+signum) 
    { 
      printf("Accept \n"); 
      socklen = sizeof(clientaddr); 
      cli_sockfd = accept(server_sockfd, 
          (struct sockaddr *)&clientaddr, 
          &socklen); 
 
      if (cli_sockfd < 0) 
      { 
        fprintf(stderr, "Accept error\n"); 
        continue; 
      } 
      PollMapi = PollMap.begin(); 
      fdpersignum = PollMapi->second; 
      clientnum = PollMapi->first+1; 
      setup_sigio(cli_sockfd, PollMapi->second.signum, PollMapi->second.pid); 
    cout << "ÇÒ´ç ¾²·¹µå ¹øÈ£ " << PollMapi->second.signum << endl;  
      PollMap.erase(PollMapi); 
 
      PollMap.insert(pair<int, FdPerSignum>(clientnum, fdpersignum)); 
    } 
    else 
    { 
      // ¿¡·¯Ã³¸® 
      cout << "Unknown Error : " << ret <<endl; 
    } 
  } 
} 
 
// °¢ ÇÁ·ÎÅäÄÝÀ» ó¸®ÇÒ ÇÔ¼ö¸¦ µî·ÏÇÑ´Ù. 
int ProtocolFuncRegist() 
{ 
  ProcessingMap["login"] = ProcessLogin;     
  ProcessingMap["list"] = ProcessList; 
  ProcessingMap["down"] = ProcessDown; 
  ProcessingMap["quit"] = ProcessQuit; 
} 
 
int main(int argc, char **argv) 
{ 
 
  FdPerSignum fdpersignum; 
  int status; 
  int loopi, loopj; 
  sigset_t sigset; 
  sigaddset(&sigset, SIGRTMIN); 
 
  int thread_num = 2;              // ¾²·¹µå Ç®ÀÇ Å©±â 
  vector<void *(*)(void *)> thread_list;    // ¾²·¹µå ¸®½ºÆ® 
    vector<pthread_t> threadident(thread_num);  // ¾²·¹µå ID ÀúÀå 
 
  // »ý¼ºµÉ ¾²·¹µåÀÇ °¹¼ö¸¸Å­ ¸®¾óŸÀÓ ½Ã±×³ÎÀ» µî·ÏÇÑ´Ù.  
  for(loopi = 0; loopi < thread_num +1; loopi ++) 
  { 
    sigaddset(&sigset, SIGRTMIN+(loopi+1)); 
  } 
 
  // µî·ÏµÈ ¸®¾óŸÀÓ ½Ã±×³ÎÀÌ ¹ß»ýÇÒ°æ¿ì ºí·°µÇµµ·Ï ¼³Á¤ÇÑ´Ù. 
  sigprocmask(SIG_BLOCK, &sigset, NULL); 
  // °¢ ÇÁ·ÎÅäÄÝÀ» ó¸®ÇÒ ÇÔ¼ö¸¦ µî·ÏÇÑ´Ù.  
  ProtocolFuncRegist(); 
 
  // Ŭ¶óÀ̾ðÆ®ÀÇ ¿¬°áÀ» ±â´Ù¸®´Â ¾²·¹µå¸¦ µî·ÏÇÑ´Ù.  
  thread_list.push_back(socket_acceptor); 
 
  // Ŭ¶óÀ̾ðÆ®ÀÇ µ¥ÀÌÅ͸¦ ó¸®ÇÏ´Â ¾²·¹µå¸¦ µî·ÏÇÑ´Ù. 
  for (loopi = 0; loopi < thread_num; loopi++) 
  { 
    thread_list.push_back(CliDataProcessing); 
  } 
 
  for (loopi = 0, loopj =1; loopi < thread_list.size(); loopi++, loopj++) 
  { 
    pthread_mutex_lock(&MutexLock); 
    pthread_create(&threadident[loopi], NULL,  
                        thread_list[loopi], 
                        (void *)&loopj); 
 
    pthread_cond_wait(&SyncCond, &MutexLock); 
 
    fdpersignum.signum = loopj; 
    fdpersignum.pid = gpid; 
    cout << "PID is " << gpid << endl;   
    if(loopi != 0) 
      PollMap.insert(pair<int, FdPerSignum>(0, fdpersignum));   
 
    pthread_mutex_unlock(&MutexLock); 
  } 
 
  for(loopi = 0; loopi < thread_list.size(); loopi ++) 
  { 
    pthread_join(threadident[loopi], (void **)&status); 
  } 
 
  return 1; 
} 
 

2 °ü·Ã ¹®¼­

3 È÷½ºÅ丮

  1. ÀÛ¼ºÀÏ : 2004³â 12¿ù 14ÀÏ
  2. ¼öÁ¤ÀÏ
    • 2012³â 12¿ù 27ÀÏ : docbook ½ºÅ¸ÀÏ ¹®¼­¸¦ wiki Çü½ÄÀ¸·Î º¯È¯


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