pollÀº select ¿Í ¸¶Âù°¡Áö·Î ´ÙÁßÀÔÃâ·Â À» ±¸ÇöÇϱâ À§ÇÑ ¹æ¹ýÀ¸·Î »ç¿ëµÇ¸ç,
µ¿½Ã¿¡ ¿©·¯°³ÀÇ Å¬¶óÀÌ¾ðÆ®¸¦ ´Ù·ç´Â ¼¹ö¸¦ Á¦ÀÛÇϱâ À§Çѹæ¹ýÀ¸·Î
ÈçÈ÷ »ç¿ëµÈ´Ù.
select ÀÇ °æ¿ì ÀÔÃâ·Â À̺¥Æ®°¡ ¹ß»ýÇßÀ» ¶§ ³Ñ°ÜÁÖ´Â Á¤º¸°¡ ³Ê¹« ÀûÀ½À¸·Î½á,
ÇÁ·Î±×·¡¹Ö½Ã ¿©±â¿¡ ½Å°æÀ» ½áÁà¾ß Çϴµ¥ poll À» ÀÌ¿ëÇϸé ÀÌ·¯ÇÑ
Á¦ÇÑÀ» ±Øº¹ÇÒ¼ö ÀÖ´Ù.
select ¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ³»¿ëÀº
select ¸¦ ÅëÇÑ ÀÔÃâ·Â ´ÙÁßÈ ¿Í
´ÙÁß¿¬°á¼¹ö ¸¸µé±â (2) ¸¦ ÂüÁ¶Çϱ⠹ٶõ´Ù.
poll
´ÙÀ½Àº pollÀÇ ÇÔ¼ö¿øÇüÀÌ´Ù.
int poll(struct poolfd *ufds, unsigned int nfds, int timeout);
|
pollÀÌ ¿©·¯°³ÀÇ ÆÄÀÏÀ» ´Ù·ç´Â ¹æ¹ýÀº select ¿Í ¸¶Âù°¡Áö·Î ÆÄÀÏÁö½ÃÀÚÀÇ
À̺¥Æ®¸¦ ±â´Ù¸®´Ù°¡ À̺¥Æ®°¡ ¹ß»ýÇϸé, poll ¿¡¼ÀÇ block ÀÌ ÇØÁ¦µÇ°í,
´ÙÀ½ ·çƾ¿¡¼ ¾î¶² ÆÄÀÏÁö½ÃÀÚ¿¡ À̺¥Æ®°¡ ¹ß»ýÇß´ÂÁö °Ë»çÇÏ´Â ¹æ½ÄÀ»
»ç¿ëÇÏ°Ô µÈ´Ù.
¿ì¼± poll ÇÔ¼öÀÇ Ã¹¹øÂ° ÀÎÀÚÀÎ pollfd ±¸Á¶Ã¼¿¡ ´ëÇØ¼ ¾Ë¾Æº¸µµ·Ï ÇϰڴÙ.
poolfd ±¸Á¶Ã¼¸¸ ¾Ë¸¸ poll ÀÇ ´ëºÎºÐÀ» ´Ù ÀÌÇØÇѰÍÀ̳ª ¸¶Âù°¡ÁöÀÌ´Ï,
ÁÖÀÇ ±í°Ô ÀÐ¾î ¹Ù¶õ´Ù.
struct pollfd
{
int fd; // °ü½ÉÀÖ¾îÇÏ´Â ÆÄÀÏÁö½ÃÀÚ
short events; // ¹ß»ýµÈ À̺¥Æ®
short revents; // µ¹·Á¹ÞÀº À̺¥Æ®
};
|
pollfd ±¸Á¶Ã¼´Â 3°³ÀÇ ¸â¹öº¯¼ö°¡ Àִµ¥, ÀÌ ±¸Á¶Ã¼¿¡
¿ì¸®°¡ °ü½ÉÀÖ¾îÇÏ´Â ÆÄÀÏÁö½ÃÀÚ¸¦
¼¼ÆÃÇϰí(fd), °ü½ÉÀÖ¾î ÇÏ´Â ÆÄÀÏÁö½ÃÀÚ°¡
¾î¶² À̺¥Æ®°¡ ¹ß»ýÇϴ°É
±â´Ù¸±°ÍÀÎÁö(events)¸¦ ÁöÁ¤ÇÏ°Ô µÈ´Ù.
±×·³ poll Àº ÇØ´ç fd ¿¡ ÇØ´ç events °¡ ¹ß»ýÇÏ´ÂÁö¸¦ °Ë»çÇÏ°Ô µÇ°í,
ÇØ´ç events °¡ ¹ß»ýÇϸé revents ¸¦ ä¿ö¼ µ¹·ÁÁÖ°Ô µÈ´Ù.
revents ´Â events °¡ ¹ß»ýÇßÀ»¶§ Ä¿³Î¿¡¼ ÀÌ events ¿¡ ¾î¶»°Ô ¹ÝÀÀ Çß´ÂÁö¿¡
´ëÇÑ ¹ÝÀÀ °ªÀÌ´Ù.
ÈÄ¿¡ revent °ªÀ» Á¶»çÇÔÀ¸·Î½á, ÇØ´ç ÆÄÀÏÁö½ÃÀÚ¿¡ ¾î¶°ÇÑ
event °¡ ÃÖÇØÁö°í Ä¿³Î¿¡¼ ±× event¸¦ ¾î¶»°Ô ó¸®Çß´ÂÁö
(ÀÔ·Â/Ãâ·ÂÀÌ Á¦´ë·Î ÀÌ·ç¾îÁ³´ÂÁö, ¾Æ´Ï¸é ¿¡·¯°¡ ¹ß»ýÇß´ÂÁö)¸¦ ¾Ë¾Æ³»¼
ÀûÀýÇÑ Á¶Ãë(ÀÐÀ» µ¥ÀÌŸ°¡ ÀÖÀ¸¸é Àаųª ÇϴµîÀÇ ÀÏ)¸¦
ÃëÇÒ¼ö ÀÖ°Ô µÈ´Ù.
±×·³ events ¿¡ ¼¼ÆÃÇÒ¼ö ÀÖ´Â events ¿¡ ´ëÇØ¼ ¾Ë¾Æº¸µµ·Ï ÇϰڴÙ.
ÀÌ °ªµéÀº <sys/poll.h> ¿¡ µðÆÄÀÎ µÇ¾î ÀÖ´Ù.
#define POLLIN 0x0001 // ÀÐÀ» µ¥ÀÌŸ°¡ ÀÖ´Ù.
#define POLLPRI 0x0002 // ±ä±ÞÇÑ ÀÐÀ» µ¥ÀÌŸ°¡ ÀÖ´Ù.
#define POLLOUT 0x0004 // ¾²±â°¡ ºÀ¼â(block)°¡ ¾Æ´Ï´Ù.
#define POLLERR 0x0008 // ¿¡·¯¹ß»ý
#define POLLHUP 0x0010 // ¿¬°áÀÌ ²÷°åÀ½
#define POLLNVAL 0x0020 // ÆÄÀÏÁö½ÃÀÚ°¡ ¿¸®Áö ¾ÊÀº°Í°°Àº
// Invalid request (À߸øµÈ ¿äû)
|
2¹øÂ° ÀÎÀÚÀÎ nfds ´Â pollfd ÀÇ ¹è¿ÀÇ Å©±â Áï ¿ì¸®°¡ Á¶»çÇÒ ÆÄÀÏÁö½ÃÀÚÀÇ
Å©±â(³×Æ®¿÷ÇÁ·Î±×·¡¹ÖÃø¸é¿¡¼ º¸ÀÚ¸é ¹Þ¾ÆµéÀϼö Àִ Ŭ¶óÀ̾ðÆ®ÀÇ Å©±â)
·Î, º¸Åë ÇÁ·Î±×·¡¹Ö ÇÒ¶§ ±×Å©±â¸¦ ÁöÁ¤ÇØÁØ´Ù.
¸¶Áö¸· ¾Æ±Ô¸ÕÆ®ÀÎ timeout ´Â select ÀÇ time ¿Í °°Àº ¿ªÇÒÀ» ÇÑ´Ù.
-
°ªÀ» ÁöÁ¤ÇÏÁö ¾ÊÀ»°æ¿ì À̺¥Æ®°¡ ¹ß»ýÇϱâ Àü±îÁö ¿µ¿øÈ÷ ±â´Ù¸°´Ù.
-
0Àϰæ¿ì´Â ±â´Ù¸®Áö ¾Ê°í °ð¹Ù·Î ´ÙÀ½ ·çƾÀ» ÁøÇàÇϰíÀÚ
-
0º¸´Ù Å« ¾çÀÇ Á¤¼öÀÏ °æ¿ì¿¡´Â ÇØ´ç ½Ã°£¸¸ÅÀ» ±â´Ù¸®°Ô µÈ´Ù.
ÇØ´ç ½Ã°£³»¿¡ ¾î¶² À̺¥Æ®°¡ ¹ß»ýÇϸé Áï½Ã µÇµ¹·Á ÁÖ¸ç,
½Ã°£À» ÃʰúÇÏ°Ô µÉ°æ¿ì 0À» return ÇÑ´Ù.
À§ÀÇ 3°¡Áö ¾Æ±Ô¸ÕÆ®¸¦ ä¿ö³ÖÀ½À¸·Î½á pollÀ» »ç¿ëÇÒ¼ö ÀÖ´Ù. poll ÇÔ¼öÀÇ
return °ªÀº int ÇüÀε¥, ¿¡·¯Àϰæ¿ì -1 ÀÌ ¸®Åϵǰí, ±×·¸Áö ¾ÊÀ»°æ¿ì
revent °¡ ¹ß»ýÇÑ pollfd ±¸Á¶Ã¼ÀÇ ¼ýÀÚ¸¦ µ¹·ÁÁÖ°Ô µÈ´Ù.
ÀÌÁ¦ poll ¹öÁ¯ÀÇ ¿ìÆíÁÖ¼Ò ÇÁ·Î±×·¥ÀÇ ¼¹ö¸¦ ÀÛ¼ºÇØ º¸µµ·Ï ÇÏÀÚ.
¿¹Á¦ : zipcode_poll.c
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/poll.h>
// ¹Þ¾ÆµéÀϼö Àִ Ŭ¶óÀ̾ðÆ®ÀÇ Å©±â
#define OPEN_MAX 600
int main(int argc, char **argv)
{
int server_sockfd, client_sockfd, sockfd;
int i, maxi;
int nread;
int state = 0;
socklen_t clilen;
struct sockaddr_in clientaddr, serveraddr;
char buf[255];
char line[255];
FILE *fp;
struct pollfd client[OPEN_MAX];
if (argc != 2)
{
printf("Usage : ./zipcode_poll [port]\n");
printf("¿¹ : ./zipcode_poll 4444\n");
exit(0);
}
if ((fp = fopen("zipcode.txt", "r")) == NULL)
{
perror("file open error : ");
exit(0);
}
if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket error : ");
exit(0);
}
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(atoi(argv[1]));
state = bind(server_sockfd, (struct sockaddr *)&serveraddr,
sizeof(serveraddr));
if (state == -1)
{
perror("bind error : ");
exit(0);
}
state = listen(server_sockfd, 5);
if (state == -1)
{
perror("listen error : ");
exit(0);
}
// pollfd ±¸Á¶Ã¼¿¡
// ¼ÒÄÏÁö½ÃÀÚ¸¦ ÇÒ´çÇÑ´Ù.
// ¼ÒÄÏ¿¡ ¾²±â events (POLLIN)¿¡ ´ëÇØ¼
// ¹ÝÀÀÇϵµ·Ï ¼¼ÆÃÇÑ´Ù.
client[0].fd = server_sockfd;
client[0].events = POLLIN;
// pollfd ±¸Á¶Ã¼ÀÇ ¸ðµç fd ¸¦ -1 ·Î ÃʱâÈ ÇÑ´Ù.
// fd °¡ -1 ÀÌ¸é ÆÄÀÏÁö½ÃÀÚ°¡ ¼¼ÆÃµÇ¾îÀÖÁö ¾Ê´Ù´Â ¶æÀÌ´Ù.
for (i = 1; i < OPEN_MAX; i++)
{
client[i].fd = -1;
}
maxi = 0;
// POLLING ½ÃÀÛ
for (;;)
{
nread = poll(client, maxi + i, 1000);
// ¸¸¾à POLLIN À̺¥Æ®¿¡ ´ëÇØ¼
// µÇµ¹·ÁÁØ À̺¥Æ®°¡(revents) POLLIN
// À̶ó¸é accept ÇÑ´Ù.
if (client[0].revents & POLLIN)
{
clilen=sizeof(clientaddr);
client_sockfd = accept(server_sockfd,
(struct sockaddr *)&clientaddr,
&clilen);
for (i = 1; i < OPEN_MAX; i++)
{
if (client[i].fd < 0)
{
client[i].fd = client_sockfd;
break;
}
}
if (i == OPEN_MAX)
{
perror("too many clients : ");
exit(0);
}
client[i].events = POLLIN;
if (i > maxi)
{
maxi = i;
}
if (--nread <= 0)
continue;
}
// ÇöÀç ÆÄÀÏÁö½ÃÀÚÀÇ ÃѰ¹¼ö ¸¸Å ·çÇÁ¸¦ µ¹¸é¼
// °¢ ÆÄÀÏÁö½ÃÀÚ¿¡ POLLIN revent °¡ ¹ß»ýÇß´ÂÁö¸¦ Á¶»çÇϰí
// POLLINÀÌ ¹ß»ýÇß´Ù¸é, ÇØ´ç ÆÄÀÏÁö½ÃÀÚ¿¡¼ µ¥ÀÌŸ¸¦ ÀоîµéÀ̰í,
// ÁÖ¼ÒÁ¤º¸¸¦ µ¹·ÁÁØ´Ù.
// ¸¸¾à "quit" ¸¦ Àоú´Ù¸é, ¼ÒÄÏ¿¬°áÀ» ²÷´Â´Ù.
for (i = 1; i <= maxi; i++)
{
if ((sockfd = client[i].fd) < 0)
continue;
if (client[i].revents & (POLLIN | POLLERR))
{
rewind(fp);
memset(buf, 0x00, 255);
if (read(sockfd, buf, 255) <= 0)
{
close(client[i].fd);
client[i].fd = -1;
}
else
{
if (strncmp(buf, "quit", 4) == 0)
{
write(sockfd, "byebye\n", 7);
close(client[i].fd);
client[i].fd = -1;
break;
}
while(fgets(line, 255, fp) != NULL)
{
if (strstr(line, buf) != NULL)
write(sockfd, line, 255);
memset(line, 0x00, 255);
}
}
}
}
}
}
|
select ¹öÁ¯ÀÎ
´ÙÁß¿¬°á¼¹ö ¸¸µé±â(2)¿Í ºñ±³Çؼ º¸±â ¹Ù¶õ´Ù.
ÄÚµù ºÐÀ§±â°¡ select ¿Í ¸Å¿ì ºñ½ÁÇÏ´Ù´Â°É ¾Ë¼ö ÀÖÀ»°ÍÀÌ´Ù.
pollfd ¿¡ ÀÔ·ÂµÈ ÆÄÀÏÁö½ÃÀÚÀÇ event ¿¡ ÀÔ·Âevent °¡ ¹ß»ýÇϸé,
Ä¿³ÎÀº ÀÔ·Âevent ¿¡ ´ëÇÑ °á°ú¸¦ µÇµ¹·ÁÁÙ°ÍÀÌ´Ù.
À̰á°ú´Â ÀÔ·Â event °¡ Á¦´ë·Î 󸮵Ǿú´Ù¸é POLLIN À» µÇµ¹·ÁÁÙ°ÍÀ̰í,
¾îµò°¡¿¡¼ ¿¡·¯°¡ ¹ß»ýÇß´Ù¸é POLLERR À» µÇµ¹·ÁÁÖ°Ô µÉ°ÍÀÌ´Ù.
±×·¯¹Ç·Î ¿ì¸®´Â revent ¸¦ °Ë»çÇÔÀ¸·Î½á, ÇØ´ç ÆÄÀÏÁö½ÃÀÚ¿¡ ÀÐÀ» µ¥ÀÌŸ°¡ Àִٴ°É
¾Ë°Ô µÇ°í, µ¥ÀÌŸ¸¦ ÀÐ¾î¼ Àû´çÇÑ Çൿ(¿©±â¿¡¼´Â ÁÖ¼Ò¸¦ µ¹·ÁÁÖ´Â)À» ÇÒ¼ö ÀÖ´Ù.
À§ÀÇ ÇÁ·Î±×·¥Àº ÀÌ·¯ÇÑ ÀÏ·ÃÀÇ °úÁ¤À» º¸¿©ÁØ´Ù.
select ¹öÁ¯°ú º°Â÷À̰¡ ¾øÀ¸¹Ç·Î select ¹öÁ¯ÀÇ ½î¾²¸¦ ÀÌÇØÇß´Ù¸é À§ÀÇ ½î¾²¸¦
ÀÌÇØÇϴµ¥ º° ¾î·Á¿òÀÌ ¾øÀ»°ÍÀÌ´Ù.
poll Àº º¸Åë select ¿¡ ºñÇØ¼ ÇØ´çÆÄÀÏÁö½ÃÀÚ¿¡ ´ëÇØ¼ º¸´Ù ¸¹Àº Á¤º¸¸¦
µÇµ¹·ÁÁÜÀ¸·Î, º¸Åë select º¸´Ù ¼±È£µÇ´Â Ãß¼¼ÀÌ´Ù.
select ¹öÁ¯°ú ¸¶Âù°¡Áö·Î polling Áß°£¿¡ ÆÄÀÏ I/O °¡ µé¾î°¥°æ¿ì,
ÆÄÀÏ I/O ÀÛ¾÷¿¡¼ÀÇ block ¶§¹®¿¡ ªÀº½Ã°£¿¡ ´Ù¼öÀÇ ¸Þ½ÃÁö¸¦ ó¸®ÇÒ°æ¿ì
¹®Á¦°¡ µÉ ¼ÒÁö°¡ ÀÖ´Ù.
±×·¯¹Ç·Î µÇµµ·ÏÀ̸é polling Áß°£¿¡ ÆÄÀÏ I/O °¡ ÀϾÁö ¾Êµµ·Ï ÇØÁÖ¾î¾ß
ÇÑ´Ù.
À§ÀÇ ½î¾²ÀÇ °æ¿ìµµ ÁÖ¼ÒÁ¤º¸¸¦ ¹Ì¸® ¸Þ¸ð¸® »ó¿¡ ¿Ã·Á³õ°í ¾²´Â°Ô ´õ¿í ÁÁÀº
¹æ¹ýÀÌ µÉ°ÍÀÌ´Ù.