FrontPage|FindPage|TitleIndex|RecentChanges|RSS socketÇÁ·Î±×·¡¹Ö±âº»
 

socket ÇÁ·Î±×·¡¹Ö ±âº» #


Linux ÇÁ·Î±×·¡¸Ó¶ó¸é socket, IO multiplexing, Asynchronous IO ¿¡ ´ëÇؼ­´Â ¾î´ÀÁ¤µµ Àͼ÷Çϸ®¶ó »ý°¢ÇÏÁö¸¸, ÀÌ ±Û¿¡¼­´Â ¼­¹ö¸¦ óÀ½ ¸¸µé¾îº¸´Â »ç¶÷µé¿¡°Ôµµ µµ¿òÀÌ µÇµµ·Ï ÃÖ´ëÇÑÀÇ ¼³¸íÀ» ºÙ¿©°¡·Á°í °èȹÁßÀÌ´Ù. ¸¹Àº ¼º¿ø ºÎŹ ;)

1 socket ÇÁ·Î±×·¡¹Ö ±âº»
1.1 socket()
1.2 bind()
1.3 listen()
1.4 read() ¿Í write()

1.1 socket() #

#include <sys/types.h>
#include <sys/socket.h>

int socket(int domain, int type, int protocol);

socket() ÇÔ¼ö´Â, Åë½ÅÀ» À§ÇÑ ³¡Á¡ ÇÑ°³¸¦ ¸¸µç´Ù (¹«½¼ ¼Ò¸®³Ä! :@). ¿ö³« ¿©·¯°¡Áö Åë½Å¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â ÇÔ¼öÀÌÁö¸¸, ÀÌ ±Û¿¡¼­´Â TCP/IP Åë½ÅÀ» À§ÇÑ ºÎºÐ¿¡ ±¹ÇÑÇؼ­, ¹º°¡ Åë½ÅÀ» ÇϱâÀ§ÇÑ ¸Å°³Ã¼(ÀÌ°ÍÀ» fd, file descriptor ¶ó°í ÇÑ´Ù)¸¦ ÇÑ°³ »ý¼ºÇϴµ¥ ¾´´Ù.

int fd; 

if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
    fprintf(stderr, "socket() error\n");
    exit(-1);
}

socket() ÇÔ¼öÀÇ ÆĶó¹ÌÅÍ domain°ú typeÀº TCP/IPÀÇ IP¿Í TCP¸¦ ÀǹÌÇÑ´Ù. Âü°í·Î UDPÅë½ÅÀ» À§Çؼ­´Â type¿¡ SOCK_DGRAM À» ¾´´Ù. ÇÁ·Î±×·¡¹Ö¿¡¼­ StreamÀ̶ó´Â ´Ü¾î´Â ¿¬¼ÓÀûÀ¸·Î ÁÖ¸£¸¤ ºÙ¾îÀÖ´Â ÀڷᱸÁ¶¸¦ °¡¸®Å°´Âµ¥, Åë½ÅÀ» ÇÏ´Ùº¸¸é Ç×»ó ¸ÕÀúº¸³½ µ¥ÀÌÅÍ°¡ ¸ÕÀú µµÂøÇÏÁö´Â ¾Ê´Âµ¥, ±×·³¿¡µµ ºÒ±¸ÇÏ°í µ¥ÀÌÅÍÀÇ ¼ø¼­¸¦ TCP¶ó´Â Åë½Å±Ô¾àÀÌ ¹Ù·ÎÀâ¾ÆÁֱ⠶§¹®¿¡ StreamÀÌ´Ù. ¹°·Ð UDP´Â ±×·±°ÍÀÌ º¸ÀåµÇÁö ¾Ê´Â´Ù.


socket()ÇÔ¼ö´Â ´ÜÁö Á¤¼ö°ª ÇÑ°³¸¦ µ¹·ÁÁִµ¥ (º¸ÅëÀº 4ÀÌ´Ù. ¿Ö³Ä¸é stdin, stdout, stderr °¡ °¢°¢ 1°³¾¿ Â÷ÁöÇÏ°í À־ 4¹ø° fd °¡ µÈ´Ù) ¾ÕÀ¸·ÎÀÇ ¸ðµç Á¶ÀÛÀº ÀÌ Á¤¼ö°ªÀ» ÅëÇؼ­ ÇÏ°Ô µÈ´Ù (´Ù¸¥ ÇÔ¼ö¸¦ È£ÃâÇÒ¶§¸¶´Ù ÀÌ °ªÀ» ³Ñ°ÜÁà¾ß ÇÑ´Ù).


1.2 bind() #

#include <sys/types.h>
#include <sys/socket.h>

int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);

bind()ÇÔ¼ö´Â Socket°ú NameÀ» ¿¬°á½ÃÄÑ(binding) ÁÖ´Â ÇÔ¼öÀÌ´Ù(¿ª½Ã ¹«½¼ ¼Ò¸®³Ä! :@). socketÀÇ ¼º°ÝÀ» ¼³¸íÇÏ´Â sockaddr¶ó´Â ±¸Á¶Ã¼ÀÇ °ªµéÀ» ¾Õ¼­ ¸¸µç fd °ª¿¡ ¿¬°á½ÃÄÑÁØ´Ù. ¿¹Á¦¸¦ º¸ÀÚ.

int port_listen = 8000;
struct sockaddr_in server_addr;

...

bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family      = PF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port        = htons(port_listen);

if((bind(fd, (struct sockaddr *)&server_addr, sizeof(server_addr))) < 0 ){
    fprintf(stderr, "bind() error\n");
    exit(-1);
}

sockaddr_in À̶ó´Â ±¸Á¶Ã¼°¡ µîÀåÇϴµ¥, bind¿¡¼­ ¿¬°áÇÒ ¼ÒÄϼӼºÀ» ´ãÀ» ±¸Á¶Ã¼ÀÌ´Ù. ¿¹Á¦¿¡¼­´Â '¾îµð¿¡¼­³ª Á¢¼Ó°¡´ÉÇÑ'(INADDR_ANY) 8000 ¹ø Æ÷Æ®¸¦ listen Çϵµ·Ï ¼³Á¤ÇÏ°í ÀÖ´Ù. bind() ¿¡¼­ ¿¡·¯°¡ ³ª´Â °æ¿ì´Â ù° ÀÌ¹Ì ´Ù¸¥ÇÁ·Î±×·¥ÀÌ ÀÌ Æ÷Æ®¸¦ ÀÌ¿ëÇÏ´Â °æ¿ì, µÑ° ´ç½ÅÀÇ ±ÇÇÑÀÌ ºÎÁ·ÇÑ °æ¿ìÀÌ´Ù. ½´ÆÛÀ¯Àú(root)¸¸ÀÌ 1024¹ø ¾Æ·¡ Æ÷Æ®¸¦ ¾µ ¼ö ÀÖ´Ù.


³»°¡ ¸¸µç ÇÁ·Î±×·¥ÀÌ ¿¹±âÄ¡¾ÊÀº ¿À·ù·Î Á¾·á Çعö¸±°æ¿ì¿¡ ±× ¾²·¹±â·Î ÀÎÇؼ­ bind() °¡ ½ÇÆÐÇÏ´Â °æ¿ì°¡ ¸¹Àºµ¥, ÀÌ·² °æ¿ì¿¡ À¯¿ëÇÑ Socket Àç»ç¿ë ¹æ¹ýÀÌ ÀÖ´Ù.

int one = 1;

setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));

º¹ÀâÇÏ°Ô »ý°¢ÇÏÁö¸»°í ±×³É ÀÌ´ë·Î º¹»çÇؼ­ ¾²¸é µÈ´Ù. setsockopt()´Â ¼ÒÄÏÀÇ ´Ù¾çÇÑ ¿É¼ÇµéÀ» ¼³Á¤ÇÒ ¼ö Àִµ¥, ÇÊÀÚ´Â ´ÜÁö Æ÷Æ® Àç»ç¿ëÀ» À§Çؼ­¸¸ »ç¿ëÇÑ´Ù --;


1.3 listen() #

#include <sys/socket.h>

int listen(int s, int backlog);

listen ÇÔ¼ö´Â, ÀÌÁ¦ Ŭ¶óÀ̾ðÆ®µéÀ» À§ÇØ ±Í¸¦ ±â¿ï¿©¶ó!ÇÏ°í ÃÖÁ¾¸í·ÉÀ» ³»¸®´Â °ÍÀÌ´Ù. ¿©Å±îÁö¸¦ Á¤¸®Çϸé, (1) socketÀ» »ý¼º (2) sockaddr_in ±¸Á¶Ã¼¸¦ ¸¸µé¾î ´ëÃæ ä¿ì°í (3) bind() ·Î 1°ú2 µÎ°³¸¦ ¹­°í, (4) listen ÇÏ´Â ¼ø¼­ÀÌ´Ù. ÀÌ·¸°Ô Çؼ­ ¼­¹ö´Â ¿¬°áÀ» ¹Þ¾ÆµéÀÏ Áغñ°¡ µÈ´Ù. ½ÇÁ¦·Î Ŭ¶óÀ̾ðÆ®°¡ ¿¬°áÀ» ÇÏ¸é ¼­¹ö´Â accept ÇÔ¼ö·Î ¿¬°áÀ» ¹Þ¾ÆµéÀÌ°í, Àû´çÇÑ ¶§¿¡ ÇØ´ç ¼ÒÄÏ¿¡¼­ µ¥ÀÌÅ͸¦ ÀÐ°í ¶Ç Àû´çÇÑ ¶§¿¡ ¾²¸é µÇ´Â °Í.


¹Ù·Î ÀÌ Àû´çÇÑ ¶§¸¦ ±¸ÇöÇÏ´Â ¹æ¹ýÀÌ »ç½Ç ¼ÒÄÏ ÇÁ·Î±×·¡¹ÖÀÇ ÇÙ½ÉÀÌ´Ù!!


1.4 read() ¿Í write() #

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);

read(), write()´Â »ç½Ç ¼ÒÄÏ°ú´Â º°·Î »ó°üÀÌ ¾øÁö¸¸, unixÀÇ ¸ðµç ÀåÄ¡´Â FILEÀÌ´Ù¶ó´Â öÇп¡ ÀÇÇØ ¼ÒÄÏ¿¡ µ¥ÀÌÅ͸¦ ¾²°Å³ª ÀÐÀ»¶§ »ç¿ëÇÑ´Ù. ÆÄÀÏ¿¡ ¾²°Å³ª ÀÐ´Â°Å¿Í ´Ù¸£Áö ¾Ê´Ù. ´Ù¸¸, ¼ÒÄÏ¿¬°áÀÌ ²÷±â°Å³ª ¿¡·¯°¡ ¹ß»ýÇßÀ» °æ¿ì ºÎ¼öÀûÀΠ󸮵éÀÌ ÇÊ¿äÇÏ´Ù.
#define MAX_BUF 1024

int nread;
char buf[MAX_BUF];

nread = read(fd, buf, MAX_BUF);

ÀÌ ¿¹Á¦´Â, fd°¡ °¡¸®Å°´Â °÷À¸·ÎºÎÅÍ µ¥ÀÌŸ¸¦ Àдµ¥ ÃÖ´ë MAX_BUF ¸¸Å­¸¸ Àд´٠(´õ ¸¹ÀÌ ÀÖ´õ¶óµµ!!). ±× °á°ú°ªÀº ½ÇÁ¦ Àо ¹ÙÀÌÆ®¼öÀÌ´Ù. ´Ù¸¸, read()ÀÇ ¸®ÅÏ°ªÀÌ 0 ¶Ç´Â -1ÀÎ °æ¿ì¿¡ À¯ÀÇÇØ¾ß ÇÑ´Ù. ´ÙÀ½À» ÂùÂùÈ÷ Àß ÀоÀÚ.

On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number.  
It is not  an error  if  this  number  is smaller than the number of bytes requested; this may happen for example because fewer 
bytes are actually  available right  now  (maybe  because we were close to end-of-file, or because we are reading from a pipe, 
or from a terminal),  or  because  read()  was interrupted  by  a  signal.  On error, -1 is returned, and errno is set appropriately. 
In this case it is left  unspecified  whether  the  file position (if any) changes.
 

0ÀÎ °æ¿ì´Â ÆÄÀÏÀÇ ³¡, -1ÀÎ °æ¿ì´Â ¿¡·¯Àε¥, ¼ÒÄÏ¿¡¼­ÀÇ ÆÄÀÏÀÇ ³¡À̶õ Åë½ÅÁ¾·á¸¦ ÀǹÌÇÒÅ×°í, ´ç¿¬È÷ ÇÁ·Î±×·¡¸Ó´Â socket Á¾·á 󸮸¦ ÇØ ÁÖ¾î¾ß ÇÑ´Ù. ¿¡·¯ÀÎ °æ¿ìµµ ¸¶Âù°¡Áö·Î Á¾·á󸮸¦ ÇØ ÁÖµµ·Ï ÇÏÀÚ (»óȲÀ» ´õ ÀÚ¼¼È÷ ±â·ÏÀ¸·Î ³²°Ü¼­ ¿Ö ¿¡·¯°¡ ¹ß»ýÇß´ÂÁö ÃßÀûÇØ º¼ ¼öµµ ÀÖ´Ù).

if(nread <= 0) {
    if(nread < 0){
        // some error handling routine
    }
    close(fd);
}

write()ÀÇ °æ¿ì´Â Á»´õ ½Å°æ½á¾ß ÇÒ ÀÏÀÌ ¸¹´Ù. ±× Áß °¡ÀåÅ©°Ô ½Å°æÀ» ½á¾ß ÇÏ´Â °ÍÀº WOULDBLOCKÀÌ´Ù. ¿î¿µÃ¼Á¦ ³»ºÎÀûÀ¸·Î Åë½ÅÀ» À§ÇÑ ¹öÆÛ¸¦ °¡Áö°í Àִµ¥, ÀÌ ¹öÆÛº¸´Ù Å« µ¥ÀÌÅ͸¦ º¸³»·Á°í Çϰųª ÀÌ¹Ì °¡µæ Â÷ Àִµ¥ ¹«¾ð°¡¸¦ ´õ º¸³»·Á°í ÇÏ´Â °æ¿ì¿¡ WOULDBLOCKÀÌ ¹ß»ýÇÏ°Ô µÈ´Ù.


ÀÌ·±ÀÏÀº ÀϽÃÀûÀÎ Åë½ÅÁöü (ÈçÈ÷ '·¢') »óȲ¿¡¼­ ÀϹÝÀûÀ¸·Î ¹ß»ýÇϴµ¥ ±×³É ¿¬°áÀ» ²÷¾î¹ö¸± ¼öµµ ¾ø°í, ¹öÆÛ°¡ ºñ¿öÁú¶§±îÁö ¹«ÀÛÁ¤ ±â´Ù¸± ¼öµµ ¾ø´Â ³ë¸©. ±×·¡¼­ Send Buffering ±â¹ýÀ» ¾´´Ù. º¸³»¾ß ÇÒ µ¥ÀÌÅÍ°¡ ¹ß»ýÇÏ¸é ¹Ù·Î Àü¼ÛÇÏÁö ¾Ê°í ¾îÇø®ÄÉÀÌ¼Ç ¹öÆÛ¿¡ ³Ö¾îµÎ¸ç, Àû´çÇÑ ½ÃÁ¡¿¡¼­ ½ÇÁ¦ Àü¼ÛÀ» ½ÃµµÇϵµ·Ï ÇÏ´Â ¹æ¹ýÀÌ´Ù. ÀÌ ±â¹ýÀº º°µµ ¹®¼­·Î ´Ù½Ã ¾µ °èȹÀÌ´Ù.

last modified 2004-06-16 11:58:45
EditText|FindPage|DeletePage|LikePages|