Rechercher une page de manuel
select_tut
Langue: ja
Version: 2006-05-13 (openSuse - 09/10/07)
Section: 2 (Appels système)
Sommaire
̾Á°
select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - Ʊ´ü I/O ¤Î¿½Å²½½ñ¼°
/* POSIX.1-2001 ¤Ë½¾¤¦¾ì¹ç */
#include <sys/select.h> /* °ÊÁ°¤Îµ¬³Ê¤Ë½¾¤¦¾ì¹ç */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h> int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); void FD_CLR(int fd, fd_set *set);
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set); #define _XOPEN_SOURCE 600 #include <sys/select.h> int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);
ÀâÌÀ
select() (¤ä pselect()) ¤Ï¡¢Æ±»þ¤ËÊ£¿ô¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿ (¤ä¥½¥±¥Ã¥È¥Ï¥ó¥É¥ë) ¤ò¸úΨŪ¤Ë°·¤ª¤¦¤È¤¹¤ë C ¥×¥í¥°¥é¥à¤Ç¡¢ÍפȤʤë´Ø¿ô¤Ç¤¢¤ë¡£ ¤³¤Î´Ø¿ô¤Î¼çÍפʰú¤¿ô¤Ï¡¢3¼ïÎà¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤ÎÇÛÎó readfds, writefds, exceptfds ¤Ç¤¢¤ë¡£ select() ¤ÎÄ̾ï¤Î»È¤ï¤ìÊý¤Ï¡¢¤Ò¤È¤Ä¤Þ¤¿¤ÏÊ£¿ô¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤Î ¡Ö¾õÂÖ¤ÎÊѲ½¡×¤òÂԤäƤ¤¤ë´Ö¡¢Ää»ß (block) ¤¹¤ë¤³¤È¤Ç¤¢¤ë¡£ ¡Ö¾õÂÖ¤ÎÊѲ½¡×¤È¤Ï¡¢°Ê²¼¤Î¤¤¤º¤ì¤«¤Î¾ì¹ç¤Ç¤¢¤ë: (1) ¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤«¤é¼èÆÀ¤Ç¤¤ëʸ»ú¤¬Áý¤¨¤¿¾ì¹ç¡¢ (2) ¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤Ë½ñ¤¹þ¤à¤¿¤á¤Î ¥«¡¼¥Í¥ë¤ÎÆâÉô¥Ð¥Ã¥Õ¥¡Æâ¤Ë»ÈÍѤǤ¤ë¶õ´Ö¤¬¤Ç¤¤¿¾ì¹ç¡¢ (3) ¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤¬¥¨¥é¡¼¤Ë¤Ê¤Ã¤¿¾ì¹ç (¥½¥±¥Ã¥È¤ä¥Ñ¥¤¥×¤Î¾ì¹ç¤Ï¡¢¤³¤ì¤ÏÀܳ¤Î¾ü¤¬¥¯¥í¡¼¥º¤µ¤ì¤¿¾ì¹ç)¡£Í×Ì󤹤ë¤È¡¢ select() ¤ÏÊ£¿ô¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤Î´Æ»ë¤ò¹Ô¤¦¤À¤±¤Î¤â¤Î¤Ç¡¢ ¤½¤ì¤ò¹Ô¤¦¤¿¤á¤Îɸ½àŪ¤Ê Unix ¥³¡¼¥ë¤Ç¤¢¤ë¡£
¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤ÎÇÛÎó¤Ï ¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿½¸¹ç (file descriptor set) ¤È¸Æ¤Ð¤ì¤ë¡£³Æ¡¹¤Î½¸¹ç¤Ï fd_set ¤È¤·¤ÆÀë¸À¤µ¤ì¡¢¤½¤ÎÆâÍÆ¤Ï FD_CLR(), FD_ISSET(), FD_SET(), FD_ZERO() ¤È¤¤¤Ã¤¿¥Þ¥¯¥í¤Ë¤è¤Ã¤ÆÊѹ¹¤Ç¤¤ë¡£ ¿·¤·¤¤¥Ç¥£¥¹¥¯¥ê¥×¥¿½¸¹ç¤ËÂФ·¤Æ¤Ï¡¢Ä̾ï FD_ZERO() ¤òºÇ½é¤Ë»È¤¦¡£ ¤½¤Î¸å¤Ç¡¢´Æ»ëÂоݤȤ·¤¿¤¤¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤ò°ì¤Ä°ì¤Ä FD_SET() ¤ÇÄɲ乤롣 select() ¤Ï¤³¤ì¤é¤Î½¸¹ç¤ÎÆâÍƤò¡¢°Ê¹ß¤Ë½Ò¤Ù¤ëµ¬Â§¤Ë½¾¤Ã¤Æ½¤Àµ¤¹¤ë¡£ select() ¤ò¸Æ¤ó¤À¸å¡¢¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤¬¤Þ¤À½¸¹ç¤Ë¸ºß¤·¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢ FD_ISSET() ¥Þ¥¯¥í¤Ë¤è¤Ã¤ÆÄ´¤Ù¤ë¤³¤È¤¬¤Ç¤¤ë¡£ FD_ISSET() ¤Ï¤½¤Î¥Ç¥£¥¹¥¯¥ê¥×¥¿¤¬½¸¹ç¤Ë¸ºß¤·¤Æ¤¤¤ì¤Ð 0 °Ê³°¤ÎÃͤòÊÖ¤·¡¢ ¸ºß¤·¤Æ¤¤¤Ê¤±¤ì¤Ð 0 ¤òÊÖ¤¹¡£ FD_CLR() ¤Ï½¸¹ç¤«¤é¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤Îºï½ü¤ò¹Ô¤¦¡£
°ú¤¿ô
- readfds
- ¤³¤Î½¸¹ç¤Ë´Þ¤Þ¤ì¤ë¤¤¤º¤ì¤«¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤Ç ¥Ç¡¼¥¿¤ÎÆɤ߹þ¤ß¤¬²Äǽ¤Ë¤Ê¤Ã¤¿¤«¤É¤¦¤«¤ò´Æ»ë¤¹¤ë¡£ select() ¤«¤éÌá¤ë»þ¤Ë¡¢readfds ¤Î¤¦¤Á¡¢ recv(2) (¥½¥±¥Ã¥È¤Î¾ì¹ç) ¤ä read(2) (¥Ñ¥¤¥×¡¢¥Õ¥¡¥¤¥ë¡¢¥½¥±¥Ã¥È¤Î¾ì¹ç) ¤Ë¤è¤Ã¤Æľ¤Á¤ËÆɤ߹þ¤ß²Äǽ¤Ê¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿°Ê³°¤Ï ½¸¹ç¤«¤éºï½ü¤µ¤ì¤ë¡£
- writefds
- ¤³¤Î½¸¹ç¤Ë´Þ¤Þ¤ì¤ë¤¤¤º¤ì¤«¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤Ç ¥Ç¡¼¥¿¤ò½ñ¤¹þ¤à¥¹¥Ú¡¼¥¹¤¬¤¢¤ë¤«¤É¤¦¤«¤ò´Æ»ë¤¹¤ë¡£ select() ¤«¤éÌá¤ë»þ¤Ë¡¢writefds ¤Î¤¦¤Á¡¢ send(2) (¥½¥±¥Ã¥È¤Î¾ì¹ç) ¤ä write(2) (¥Ñ¥¤¥×¡¢¥Õ¥¡¥¤¥ë¡¢¥½¥±¥Ã¥È¤Î¾ì¹ç) ¤Ë¤è¤Ã¤Æľ¤Á¤Ë½ñ¤¹þ¤ß²Äǽ¤Ê¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿°Ê³°¤Ï ½¸¹ç¤«¤éºï½ü¤µ¤ì¤ë¡£
- exceptfds
- ¤³¤Î½¸¹ç¤Ë´Þ¤Þ¤ì¤ë¤¤¤º¤ì¤«¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤Ç Îã³°¤ä¥¨¥é¡¼¤¬À¸¤¸¤Æ¤¤¤ë¤«¤É¤¦¤«¤ò´Æ»ë¤¹¤ë¡£ ¤·¤«¤·¡¢¤³¤ì¤Ï¤¿¤À¤Î±½¤Ë²á¤®¤º¡¢ ¼ÂºÝ¤Ë exceptfds ¤Ç´Æ»ë¤·¤Æ¤¤¤ë¤â¤Î¤Ï ÂÓ°è³° (out-of-band: OOB) ¥Ç¡¼¥¿¤Ê¤Î¤À¡£ OOB ¥Ç¡¼¥¿¤Ï¥½¥±¥Ã¥È¤Ç MSG_OOB ¥Õ¥é¥°¤òÍѤ¤¤ë¤ÈÁ÷¿®¤µ¤ì¤ë¡£ ½¾¤Ã¤Æ¡¢¼ÂºÝ¤Ë¤Ï exceptfds ¤Ï¥½¥±¥Ã¥È¤Ë¤·¤«Å¬ÍѤǤ¤Ê¤¤¡£ ¤³¤Î¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï recv(2) ¤È send(2) ¤ò¸«¤è¡£ select() ¤«¤éÌá¤ë»þ¤Ë¡¢exceptfds ¤Î¤¦¤Á¡¢ OOB ¥Ç¡¼¥¿¤ÎÆɤ߹þ¤ß¤¬²Äǽ¤Ë¤Ê¤Ã¤Æ¤¤¤ë¥Ç¥£¥¹¥¯¥ê¥×¥¿°Ê³°¤Ï ½¸¹ç¤«¤éºï½ü¤µ¤ì¤ë¡£ OOB ¥Ç¡¼¥¿¤ÎÆɤ߹þ¤ß (recv(2) ¤Ç¹Ô¤¦) ¤Ï 1 ¥Ð¥¤¥È¤À¤±¤·¤«¤Ç¤¤Ê¤¤¤¬¡¢ OOB ¥Ç¡¼¥¿¤Î½ñ¤¹þ¤ß (send(2) ¤Ç¹Ô¤¦) ¤Ï¤¤¤Ä¤Ç¤â¤Ç¤¡¢ Ää»ß (block) ¤µ¤ì¤ë¤³¤È¤â¤Ê¤¤¡£ ½¾¤Ã¤Æ¡¢¥½¥±¥Ã¥È¤Ë OOB ¥Ç¡¼¥¿¤Î½ñ¤¹þ¤ß¤¬²Äǽ¤Ç¤¢¤ë¤«¤É¤¦¤«¤ò¥Á¥§¥Ã¥¯¤¹¤ë 4 ÈÖÌܤν¸¹ç¤ÏɬÍפʤ¤¤Î¤Ç¤¢¤ë¡£
- nfds
- Á´¤Æ¤Î½¸¹ç¤Ë´Þ¤Þ¤ì¤ë¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤Î¤¦¤Á¡¢ Ãͤ¬ºÇÂç¤Î¤â¤Î¤Ë 1 ¤ò¤·¤¿À°¿ô¤Ç¤¢¤ë¡£ ¤¹¤Ê¤ï¤Á¡¢¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤ò½¸¹ç¤Ë²Ã¤¨¤ëºî¶È¤ÎÅÓÃæ¤Ç¡¢ Á´¤Æ¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤ò¸«¤ÆºÇÂçÃͤòµá¤á¡¢ ¤½¤ì¤Ë 1 ¤ò²Ã¤¨¤Æ nfds ¤È¤·¤Æ select() ¤ËÅϤµ¤Ê¤¤¤È¤¤¤±¤Ê¤¤¡¢¤È¤¤¤¦¤³¤È¤À¡£
- utimeout
-
- (²¿¤âµ¯¤³¤é¤Ê¤«¤Ã¤¿¾ì¹ç¤Ë) select() ¤¬Ìá¤ëÁ°¤ËÂԤĺÇÂç»þ´Ö¤Ç¤¢¤ë¡£ ¤³¤ÎÃÍ¤Ë NULL ¤òÅϤ¹¤È¡¢ select() ¤Ï²¿¤é¤«¤Î¥¤¥Ù¥ó¥È¤òÂÔ¤Á¤Ä¤Å¤±¤Æ¤º¤Ã¤ÈÄä»ß¤¹¤ë¡£ utimeout ¤Ï 0 Éäˤ¹¤ë¤³¤È¤â¤Ç¤¡¢ ¤³¤Î¾ì¹ç select() ¤Ïľ¤Á¤ËÌá¤ë¡£ ¹½Â¤ÂÎ struct timeval ¤Ï¼¡¤Î¤è¤¦¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤ë:
-
struct timeval { time_t tv_sec; /* seconds */ long tv_usec; /* microseconds */ };
- (²¿¤âµ¯¤³¤é¤Ê¤«¤Ã¤¿¾ì¹ç¤Ë) select() ¤¬Ìá¤ëÁ°¤ËÂԤĺÇÂç»þ´Ö¤Ç¤¢¤ë¡£ ¤³¤ÎÃÍ¤Ë NULL ¤òÅϤ¹¤È¡¢ select() ¤Ï²¿¤é¤«¤Î¥¤¥Ù¥ó¥È¤òÂÔ¤Á¤Ä¤Å¤±¤Æ¤º¤Ã¤ÈÄä»ß¤¹¤ë¡£ utimeout ¤Ï 0 Éäˤ¹¤ë¤³¤È¤â¤Ç¤¡¢ ¤³¤Î¾ì¹ç select() ¤Ïľ¤Á¤ËÌá¤ë¡£ ¹½Â¤ÂÎ struct timeval ¤Ï¼¡¤Î¤è¤¦¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤ë:
- ntimeout
-
- ¤³¤Î°ú¤¿ô¤Ï utimeout ¤ÈƱ¤¸°ÕÌ£¤ò»ý¤Ä¤¬¡¢ struct timespec ¤Ï¼¡¤Ë¼¨¤¹¤è¤¦¤Ë¥Ê¥ÎÉäÎÀºÅÙ¤ò»ý¤Ä¡£
-
struct timespec { long tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ };
- ¤³¤Î°ú¤¿ô¤Ï utimeout ¤ÈƱ¤¸°ÕÌ£¤ò»ý¤Ä¤¬¡¢ struct timespec ¤Ï¼¡¤Ë¼¨¤¹¤è¤¦¤Ë¥Ê¥ÎÉäÎÀºÅÙ¤ò»ý¤Ä¡£
- sigmask
- ¤³¤Î°ú¤¿ô¤Ï pselect() ¥³¡¼¥ë¤Î¼Â¹ÔÃæ¤Ëµö²Ä¤µ¤ì¤ë ¥·¥°¥Ê¥ë¤Î½¸¹ç¤òÊÝ»ý¤¹¤ë (sigaddset(3) ¤ª¤è¤Ó sigprocmask(2) ¤ò»²¾È)¡£¤³¤ì¤Ë¤Ï NULL ¤òÅϤ¹¤³¤È¤â¤Ç¤¡¢ ¤½¤Î¾ì¹ç¤Ï¤³¤Î´Ø¿ô¤ØÆþ¤ë¤È¤¡¦½Ð¤ë¤È¤¤Ëµö²Ä¥·¥°¥Ê¥ë¤Î½¸¹ç¤òÊѹ¹¤·¤Ê¤¤¡£ ¤½¤Î¸å¤Ï select() ¤ÈÁ´¤¯Æ±ÍͤÎÆ°ºî¤ò¤¹¤ë¡£
¥·¥°¥Ê¥ë¤È¥Ç¡¼¥¿¥¤¥Ù¥ó¥È¤òÁȤ߹ç¤ï¤»¤ë
¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤«¤é¡¢¥Ç¡¼¥¿¤À¤±¤Ç¤Ê¤¯¥·¥°¥Ê¥ë¤âÂÔ¤Á¤¿¤¤¤È¤¤Ë¤Ï pselect() ¤ò»È¤¦É¬Íפ¬¤¢¤ë¡£¥·¥°¥Ê¥ë¤ò¥¤¥Ù¥ó¥È¤È¤·¤Æ¼õ¿®¤¹¤ë¥×¥í¥°¥é¥à¤Ï¡¢ ÂçÄñ¥·¥°¥Ê¥ë¥Ï¥ó¥É¥é¤ò¥°¥í¡¼¥Ð¥ë¤Ê¥Õ¥é¥°¤òΩ¤Æ¤ë¤¿¤á¤À¤±¤Ë»È¤¦¡£ ¤³¤Î¥°¥í¡¼¥Ð¥ë¤Ê¥Õ¥é¥°¤Ï¡¢ ¤½¤Î¥¤¥Ù¥ó¥È¤ò¥×¥í¥°¥é¥à¤Î¥á¥¤¥ó¥ë¡¼¥×¤Ç ½èÍý¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤³¤È¤ò¼¨¤¹¡£ ¥·¥°¥Ê¥ë¤ò¼õ¤±¤ë¤È select() (¤ä pselect()) ¤Ï errno ¤Ë EINTR ¤ò¥»¥Ã¥È¤·¤ÆÌá¤ë¤³¤È¤Ë¤Ê¤ë¡£ ¥·¥°¥Ê¥ë¤¬¥×¥í¥°¥é¥à¤Î¥á¥¤¥ó¥ë¡¼¥×¤Ç½èÍý¤µ¤ì¤ë¤¿¤á¤Ë¤Ï¤³¤ÎÆ°ºî¤¬ÉԲķç¤Ç¡¢ ¤³¤ì¤¬¤Ê¤¤¤È select() ¤Ï±Ê±ó¤ËÄä»ß¤·Â³¤±¤ë¤³¤È¤Ë¤Ê¤ë¡£ ¤µ¤Æ¡¢¥á¥¤¥ó¥ë¡¼¥×¤Î¤É¤³¤«¤Ë¤³¤Î¥°¥í¡¼¥Ð¥ë¥Õ¥é¥°¤ò¥Á¥§¥Ã¥¯¤¹¤ë ¾ò·ïʸ¤¬¤¢¤ë¤È¤·¤è¤¦¡£¤³¤³¤Ç¾¯¤·¹Í¤¨¤Æ¤ß¤Ê¤¤¤È¤¤¤±¤Ê¤¤¡£ ¡Ö¥·¥°¥Ê¥ë¤¬¾ò·ïʸ¤Î¸å¡¢¤·¤«¤· select() ¥³¡¼¥ë¤ÎÁ°¤ËÅþÃ夷¤¿¤é ¤É¤¦¤Ê¤ë¤Î¤«¡©¡× Åú¤¨¤Ï¡Ö¤½¤Î select() ¤Ï¡¢¤¿¤È¤¨²ò·èÂÔ¤Á¤Î¥¤¥Ù¥ó¥È¤¬¤¢¤Ã¤¿¤È¤·¤Æ¤â¡¢ ±Ê±ó¤ËÄä»ß¤¹¤ë¡×¤Ç¤¢¤ë¡£ ¤³¤Î¶¥¹ç¾õÂÖ¤Ï pselect() ¥³¡¼¥ë¤Ë¤è¤Ã¤Æ²ò·è¤Ç¤¤ë¡£ pselect() ¥³¡¼¥ë¤Ï¡¢¼«Ê¬¼«¿È¤ÎÆâÉô°Ê³°¤Ç¤Ï¼õ¿®¤·¤¿¤¯¤Ê¤¤¥·¥°¥Ê¥ë¤ò ¥Þ¥¹¥¯¤·¤Æ½ü³°¤¹¤ë¤Î¤Ë»ÈÍѤǤ¤ë¡£ Î㤨¤Ð¡¢ÌäÂê¤È¤Ê¤Ã¤Æ¤¤¤ë¥¤¥Ù¥ó¥È¤¬»Ò¥×¥í¥»¥¹¤Î½ªÎ»¤Î¾ì¹ç¤ò¹Í¤¨¤è¤¦¡£ ¥á¥¤¥ó¥ë¡¼¥×¤¬»Ï¤Þ¤ëÁ°¤Ë¡¢ SIGCHLD ¤ò sigprocmask(2) ¤Ç¥Ö¥í¥Ã¥¯¤¹¤ë¡£ pselect() ¥³¡¼¥ë¤Ç¤Ï SIGCHLD ¤ò¡¢¤â¤È¤â¤È¤Î¥·¥°¥Ê¥ë¥Þ¥¹¥¯¤ò »È¤Ã¤Æ͸ú¤Ë¤¹¤ë¤Î¤À¡£¤³¤Î¥×¥í¥°¥é¥à¤Ï¼¡¤Î¤è¤¦¤Ë¤Ê¤ë¡£int child_events = 0; void child_sig_handler(int x) { child_events++; signal(SIGCHLD, child_sig_handler); } int main(int argc, char **argv) { sigset_t sigmask, orig_sigmask; sigemptyset(&sigmask); sigaddset(&sigmask, SIGCHLD); sigprocmask(SIG_BLOCK, &sigmask, &orig_sigmask); signal(SIGCHLD, child_sig_handler); for (;;) { /* main loop */ for (; child_events > 0; child_events--) { /* do event work here */ } r = pselect(nfds, &rd, &wr, &er, 0, &orig_sigmask); /* main body of program */ } }
¼ÂÎã
¼ÂºÝ¤Î¤È¤³¤í select() ¤ÎÂç»ö¤ÊÅÀ¤Ï²¿¤Ê¤Î¤«¡© ¥Ç¥£¥¹¥¯¥ê¥×¥¿¤Ï¹¥¤¤Ê¤È¤¤ËÆɤ߽ñ¤¤Ç¤¤ë¤ó¤¸¤ã¤Ê¤¤¤Î¡© select() ¤Î½ÅÍפʤȤ³¤í¤Ï¡¢Ê£¿ô¤Î¥Ç¥£¥¹¥¯¥ê¥×¥¿¤òƱ»þ¤Ë´Æ»ë¤Ç¤¡¢ ¤Ê¤ó¤ÎÆ°¤¤â¤Ê¤±¤ì¤Ð¥×¥í¥»¥¹¤òŬÀڤ˥¹¥ê¡¼¥×¾õÂ֤˰ܹԤ¹¤ë¤È¤³¤í¤Ë¤¢¤ë¤Î¤À¡£ select() ¤òÍѤ¤¤ì¤Ð¡¢Ê£¿ô¤Î¥Ñ¥¤¥×¤ä¥½¥±¥Ã¥È¤òƱ»þ¤Ë°·¤¤¤Ê¤¬¤é ¤³¤ì¤¬¹Ô¤¨¤ë¡£Unix ¥×¥í¥°¥é¥Þ¤Ï¡¢ Ê£¿ô¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤ÎÆþ½ÐÎϤòƱ»þ¤Ë°·¤ï¤Í¤Ð¤Ê¤é¤º¡¢ ¤·¤«¤â¥Ç¡¼¥¿¤Îή¤ì¤Ï´Ö·çŪ¤Ç¤¢¤ë¡¢¤È¤¤¤¦¾õ¶·¤Ë¤è¤¯½Ð²ñ¤¦¡£ ñ¤Ë read(2) ¤ä write(2) ¥³¡¼¥ë¤Î¥·¡¼¥±¥ó¥¹¤òºî¤ë¤À¤±¤Ç¤Ï¡¢¤½¤ì¤é¤Î¥³¡¼¥ë¤Î¤É¤ì¤«¤¬ ¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤«¤é¤Î¥Ç¡¼¥¿¤òÂԤäƥ֥í¥Ã¥¯¤·¤Æ¤ª¤ê¡¢ ¾¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤Ë¤Ï¥Ç¡¼¥¿¤¬ÅþÃ夷¤Æ¤¤¤ë¤Î¤Ë»È¤¨¤Ê¤¤¡¢ ¤È¤¤¤¦¤³¤È¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¤À¤í¤¦¡£ select() ¤ò»È¤¦¤È¤³¤Î¾õ¶·¤Ë¸ú²ÌŪ¤ËÂнè¤Ç¤¤ë¡£select() ¤ò»È¤Ã¤¿´Êñ¤ÊÎ㤬 select(2) ¤Î¥Þ¥Ë¥å¥¢¥ë¥Ú¡¼¥¸¤Ë½ñ¤«¤ì¤Æ¤¤¤ë¡£
SELECT ¤ÎÙÝ
select() ¤ò»È¤ª¤¦¤È¤·¤¿Â¿¤¯¤Î¿Í¤Ï¡¢Íý²ò¤·¤Ë¤¯¤¤µóÆ°¤Ë½Ð¤¯¤ï¤·¡¢·ë²ÌŪ¤Ë ¤Ç¤¤¿¤â¤Î¤Ï°Ü¿¢À¤¬¤Ê¤¤¤«¡¢¤è¤¯¤Æ¤â¥®¥ê¥®¥ê¤Î¤â¤Î¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¡£ Î㤨¤Ð¡¢¾åµ¤Î¥×¥í¥°¥é¥à¤Ï¡¢ ½¸¹ç¤Ë´Þ¤Þ¤ì¤ë¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤òÈó¥Ö¥í¥Ã¥¯¥â¡¼¥É (ioctl(2) »²¾È) ¤Ë¤·¤Ê¤¯¤Æ¤â¡¢¤É¤³¤Ë¤â¥Ö¥í¥Ã¥¯¤¬À¸¤¸¤Ê¤¤¤è¤¦Ãí°Õ¤·¤Æ½ñ¤«¤ì¤Æ¤¤¤ë¡£ Èù̯¤Ê´Ö°ã¤¤¤Ë¤è¤Ã¤Æ¡¢ select() ¤ò»È¤¦ÍøÅÀ¤Ï´Êñ¤Ë¼º¤ï¤ì¤Æ¤·¤Þ¤¦¡£ ¤½¤³¤Ç¤³¤³¤Ç¤Ï¡¢ select() ¥³¡¼¥ë¤ò»È¤¦¤È¤¤ËÃí°Õ¤¹¤Ù¤½ÅÍ×»ö¹à¤ò¥ê¥¹¥È¤·¤è¤¦¤È»×¤¦¡£- 1.
- select() ¤ò»È¤¦¤È¤¤Ï¡¢¥¿¥¤¥à¥¢¥¦¥È¤ÏÀßÄꤹ¤Ù¤¤Ç¤Ê¤¤¡£ ½èÍý¤¹¤ë¥Ç¡¼¥¿¤¬Ìµ¤¤¤È¤¤Ë¤Ï¡¢ ¤¢¤Ê¤¿¤Î¥×¥í¥°¥é¥à¤Ë¤Ï²¿¤â¤¹¤ë¤³¤È¤Ï̵¤¤¤Ï¤º¤Ç¤¢¤ë¡£ ¥¿¥¤¥à¥¢¥¦¥È¤Ë°Í¸¤·¤¿¥³¡¼¥É¤ÏÄ̾ï°Ü¿¢À¤¬¤Ê¤¯¡¢ ¥Ç¥Ð¥Ã¥°¤âÆñ¤·¤¯¤Ê¤ë¡£
- 2.
- ¾å½Ò¤·¤¿¤è¤¦¤Ë¡¢ ¸úΨŪ¤Ê¥×¥í¥°¥é¥à¤ò½ñ¤¯¤Ë¤Ï nfds ¤ÎÃͤòŬÀڤ˷׻»¤·¤ÆÍ¿¤¨¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
- 3.
- select() ¥³¡¼¥ë¤Î½ªÎ»¸å¤Ë·ë²Ì¤ò¥Á¥§¥Ã¥¯¤·¤Æ¡¢ ŬÀÚ¤ËÂбþ¤¹¤ë¤Ä¤â¤ê¤Î¤Ê¤¤¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤Ï¡¢ ¤É¤Î½¸¹ç¤Ë¤â²Ã¤¨¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ ¼¡¤Î¥ë¡¼¥ë¤â»²¾È¡£
- 4.
- select() ¤«¤éÊ֤俸å¤Ë¤Ï¡¢Á´¤Æ¤Î½¸¹ç¤ÎÁ´¤Æ¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤Ë¤Ä¤¤¤Æ Æɤ߽ñ¤²Äǽ¤Ê¾õÂ֤ˤʤäƤ¤¤ë¤«¤ò¥Á¥§¥Ã¥¯¤¹¤Ù¤¤Ç¤¢¤ë¡£
- 5.
- read(2), recv(2), write(2), send(2) ¤È¤¤¤Ã¤¿´Ø¿ô¤Ï¡¢¤³¤Á¤é¤¬Í׵ᤷ¤¿Á´¥Ç¡¼¥¿¤òÆɤ߽ñ¤¤¹¤ëɬÍפϤʤ¤¡£ ¤â¤·Á´¥Ç¡¼¥¿¤òÆɤ߽ñ¤¤¹¤ë¤Ê¤é¡¢¤½¤ì¤Ï¥È¥é¥Õ¥£¥Ã¥¯¤ÎÉé²Ù¤¬¾®¤µ¤¯¡¢ ¥¹¥È¥ê¡¼¥à¤¬Â®¤¤¾ì¹ç¤À¤í¤¦¡£¤³¤Î¾ò·ï¤Ï¾ï¤ËËþ¤¿¤µ¤ì¤ë¤È¤Ï¸Â¤é¤Ê¤¤¡£ ¤³¤ì¤é¤Î´Ø¿ô¤¬´èÄ¥¤Ã¤Æ¤â 1 ¥Ð¥¤¥È¤·¤«Á÷¼õ¿®¤Ç¤¤Ê¤¤¤è¤¦¤Ê¾ì¹ç¤â ¹Íθ¤ËÆþ¤ì¤Æ¤ä¤é¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
- 6.
- ½èÍý¤¹¤ë¥Ç¡¼¥¿Î̤¬¾®¤µ¤¤¤³¤È¤¬¤Ï¤Ã¤¤ê¤È¤ï¤«¤Ã¤Æ¤¤¤ë¾ì¹ç¤ò½ü¤¤¤Æ¡¢ °ìÅÙ¤Ë 1 ¥Ð¥¤¥È¤º¤ÄÆɤ߽ñ¤¤¹¤ë¤è¤¦¤Ê¤³¤È¤Ï¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ ¥Ð¥Ã¥Õ¥¡¤Îµö¤¹¤«¤®¤ê¤Î¥Ç¡¼¥¿¤ò¤Þ¤È¤á¤ÆÆɤ߽ñ¤¤·¤Ê¤¤¤È¡¢ Èó¾ï¤Ë¸úΨ¤¬°¤¤¡£¾åµ¤ÎÎã¤Ç¤Ï¥Ð¥Ã¥Õ¥¡¤Ï 1024 ¥Ð¥¤¥È¤Ë¤·¤Æ¤¤¤ë¤¬¡¢ ¤³¤Î¥µ¥¤¥º¤òÂ礤¯¤¹¤ë¤Î¤Ï´Êñ¤À¤í¤¦¡£
- 7.
- read(2), recv(2), write(2), send(2) ¤Ê¤É¤Î´Ø¿ô¤ä select() ¥³¡¼¥ë¤Ï¡¢ errno ¤ò EINTR ¤ä EAGAIN (EWOULDBLOCK) ¤Ë¤·¤Æ -1 ¤òÊÖ¤¹¤³¤È¤¬¤¢¤ë¡£ ¤³¤Î¤è¤¦¤Ê·ë²Ì¤ËÂФ·¤ÆŬÀÚ¤ËÂбþ¤·¤Æ¤ä¤é¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤ (¾åµ¤ÎÎã¤Ç¤Ï¤·¤Æ¤¤¤Ê¤¤)¡£ ½ñ¤¤¤Æ¤¤¤ë¥×¥í¥°¥é¥à¤¬¥·¥°¥Ê¥ë¤ò¼õ¤±¤ëͽÄ꤬¤Ê¤±¤ì¤Ð¡¢ EINTR ¤¬ÊÖ¤µ¤ì¤ë¤³¤È¤Ï¤¢¤Þ¤ê¹Í¤¨¤é¤ì¤Ê¤¤¡£ ½ñ¤¤¤Æ¤¤¤ë¥×¥í¥°¥é¥à¤ÇÈó¥Ö¥í¥Ã¥¯ I/O ¤ò¥»¥Ã¥È¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢ EAGAIN ¤¬ÊÖ¤µ¤ì¤ë¤³¤È¤Ï¤Ê¤¤¤À¤í¤¦¡£¤½¤ì¤Ç¤â¤Ê¤ª¡¢ ´°Á´¤ò´ü¤¹¤ë¤Ê¤é¤Ð¡¢¤³¤ì¤é¤Î¥¨¥é¡¼¤ò¹Íθ¤ËÆþ¤ì¤ëɬÍפ¬¤¢¤ë¡£
- 8.
- ·è¤·¤Æ¡¢°ú¤¿ô¤ËŤµ 0 ¤Î¥Ð¥Ã¥Õ¥¡¤ò»ØÄꤷ¤Æ read(2), recv(2), write(2), send(2) ¤ò¸Æ¤Ó½Ð¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
- 9.
- read(2), recv(2), write(2), send(2) ¤¬ 7. ¤Ë¼¨¤·¤¿°Ê³°¤Î¥¨¥é¡¼¤Ç¼ºÇÔ¤·¤¿¾ì¹ç¤ä¡¢ ÆþÎϷϤδؿô¤Î°ì¤Ä¤¬¥Õ¥¡¥¤¥ëËöÈø¤òɽ¤¹ 0 ¤òÊÖ¤·¤¿¾ì¹ç¤Ï¡¢ ¤½¤Î¥Ç¥£¥¹¥¯¥ê¥×¥¿¤ò¤â¤¦°ìÅÙ select ¤ËÅϤ·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ ¾åµ¤ÎÎã¤Ç¤Ï¡¢¤½¤Î¥Ç¥£¥¹¥¯¥ê¥×¥¿¤ò¤¿¤À¤Á¤Ë¥¯¥í¡¼¥º¤·¡¢ ¤½¤³¤Ë¤Ï -1 ¤ò¥»¥Ã¥È¤·¤Æ¡¢ ¤½¤ì¤¬½¸¹ç¤Ë´Þ¤Þ¤ì³¤±¤ë¤Î¤òµö¤µ¤Ê¤¤¤è¤¦¤Ë¤·¤Æ¤¤¤ë¡£
- 10.
- ¥¿¥¤¥à¥¢¥¦¥È¤ÎÃÍ¤Ï select() ¤ò¸Æ¤Ö¤¿¤Ó¤Ë½é´ü²½¤¹¤Ù¤¤Ç¤¢¤ë¡£ OS ¤Ë¤è¤Ã¤Æ¤Ï timeout ¹½Â¤ÂΤ¬Êѹ¹¤µ¤ì¤ë¾ì¹ç¤¬¤¢¤ë¤«¤é¤Ç¤¢¤ë¡£ ⤷¡¢ pselect() ¤Ï¼«Ê¬¤Î timeout ¹½Â¤ÂΤòÊѹ¹¤¹¤ë¤³¤È¤Ï¤Ê¤¤¡£
- 11.
- ʹ¤¤¤¿¤È¤³¤í¤Ç¤Ï¡¢Windows ¤Î¥½¥±¥Ã¥ÈÁØ¤Ï OOB ¥Ç¡¼¥¿¤òÀµ¤·¤¯½èÍý¤·¤Ê¤¤¤é¤·¤¤¡£ ¤Þ¤¿¡¢¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤¬Á´¤¯¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤Ê¤¤¤è¤¦¤Ê select() ¥³¡¼¥ë¤âÀµ¤·¤¯½èÍý¤·¤Ê¤¤¤é¤·¤¤¡£ ¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤ò°ìÀÚÀßÄꤷ¤Ê¤¤¤Ç timeout ¤ò»È¤¦¤ä¤êÊý¤Ï¡¢ 1 Éðʲ¼¤ÎÀºÅÙ¤Ç¥×¥í¥»¥¹¤ò¥¹¥ê¡¼¥×¤µ¤»¤ë¤Ë¤ÏÊØÍø¤ÊÊýË¡¤Ê¤Î¤À¤¬ (³¤¤ò¸«¤è)¡£
usleep ¥¨¥ß¥å¥ì¡¼¥·¥ç¥ó
usleep(3) ´Ø¿ô¤ò»ý¤¿¤Ê¤¤¥·¥¹¥Æ¥à¤Ç¤Ï¡¢ ͸¤Υ¿¥¤¥à¥¢¥¦¥È¤ò»ØÄꤷ¡¢¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤òÁ´¤¯¥»¥Ã¥È¤»¤º¤Ë select() ¤ò¸Æ¤Ó½Ð¤¹¤³¤È¤Ç¡¢¤³¤ì¤òÂåÍѤǤ¤ë¡£ °Ê²¼¤Î¤è¤¦¤Ë¤¹¤ë¡£struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 200000; /* 0.2 seconds */ select(0, NULL, NULL, NULL, &tv);
⤷¡¢¤³¤ì¤¬Æ°¤¯¤ÈÊݾڤµ¤ì¤Æ¤¤¤ë¤Î¤Ï Unix ¥·¥¹¥Æ¥à¤Ë¸Â¤é¤ì¤ë¡£
ÊÖ¤êÃÍ
À®¸ù¤¹¤ë¤È¡¢ select() ¤Ï¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿½¸¹ç¤Ë»Ä¤Ã¤Æ¤¤¤ë ¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤ÎÁí¿ô¤òÊÖ¤¹¡£select() ¤¬¥¿¥¤¥à¥¢¥¦¥È¤¹¤ë¤È¡¢ÊÖ¤êÃÍ¤Ï 0 ¤Ë¤Ê¤ë¡£ ¤½¤Î»þ¡¢¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿½¸¹ç¤Ï¤¹¤Ù¤Æ¶õ¤Ç¤¢¤ë (¤·¤«¤·¤½¤¦¤Ê¤é¤Ê¤¤¥·¥¹¥Æ¥à¤â¤¢¤ë)¡£
ÊÖ¤êÃͤ¬ -1 ¤Î¾ì¹ç¤Ï¥¨¥é¡¼¤ò°ÕÌ£¤·¡¢ errno ¤¬Å¬Àڤ˥»¥Ã¥È¤µ¤ì¤ë¡£¥¨¥é¡¼¤¬µ¯¤³¤Ã¤¿¾ì¹ç¡¢ ÊÖ¤µ¤ì¤¿½¸¹ç¤ä timeout ¹½Â¤ÂΤÎÆâÍƤÏ̤ÄêµÁ¤È¤Ê¤Ã¤Æ¤¤¤ë¤Î¤Ç¡¢ »È¤¦¤Ù¤¤Ç¤Ï¤Ê¤¤¡£ ¤·¤«¤· pselect() ¤Ï·è¤·¤Æ ntimeout ¤òÊѹ¹¤·¤Ê¤¤¡£
Ãí°Õ
°ìÈÌŪ¤Ë¸À¤Ã¤Æ¡¢¥½¥±¥Ã¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ëÁ´¤Æ¤Î¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Ï select() ¤â¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¡£ select() ¤ò»È¤ï¤Ê¤¤¤È¤â¤Î¤¹¤´¤¯Ê£»¨¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¥×¥í¥°¥é¥à¤¬Â¿¤¤¡£ select() ¤ò»È¤¦¤È¡¢¥×¥í¥°¥é¥Þ¤¬¥¹¥ì¥Ã¥É¡¢¥Õ¥©¡¼¥¯¡¢IPC¡¢¥·¥°¥Ê¥ë¡¢¥á¥â¥ê¶¦Í¡¢ Åù¡¹¤ò»È¤Ã¤Æ¤â¤Ã¤ÈÊ£»¨¤ÊÊýË¡¤Ç²ò·è¤·¤è¤¦¤È¤¹¤ë¿¤¯¤ÎÌäÂ꤬¡¢ °Ü¿¢À¤¬¤¢¤ê¤«¤Ä¸úΨŪ¤ÊÊýË¡¤Ç²ò·è¤Ç¤¤ë¡£poll(2) ¥·¥¹¥Æ¥à¥³¡¼¥ë¤Ï select() ¤ÈƱ¤¸µ¡Ç½¤ò»ý¤Ã¤Æ¤ª¤ê¡¢ ¤Þ¤Ð¤é¤Ê¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿½¸¹ç¤ò´Æ»ë¤¹¤ë¾ì¹ç¤Ë ¤¤¤¯¤é¤«¸úΨ¤¬¤è¤¤¡£ ¸½ºß¤Ç¤Ï¹¤¯ÍøÍѲÄǽ¤Ç¤¢¤ë¤¬¡¢°ÊÁ°¤Ï select() ¤è¤ê°Ü¿¢À¤ÎÌ̤ÇÎô¤Ã¤Æ¤¤¤¿¡£
Linux Æȼ«¤Î epoll(7) API ¤Ï¡¢Â¿¿ô¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿¤ò´Æ»ë¤¹¤ë¾ì¹ç¤Ë select(2) ¤ä poll(2) ¤è¤ê¤â¸úΨŪ¤Ê¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤òÄ󶡤·¤Æ¤¤¤ë¡£
Îã
select() ¤ÎËÜÅö¤ËÊØÍø¤ÊÅÀ¤ò¼¨¤¹¡¢¤è¤¤Îã¤ò¾Ò²ð¤¹¤ë¡£ °Ê²¼¤Î¥ê¥¹¥È¤Ï¡¢¤¢¤ë TCP ¥Ý¡¼¥È¤«¤éÊ̤Υݡ¼¥È¤ØžÁ÷¤ò¹Ô¤¦ TCP ¥Õ¥©¥ï¡¼¥É¥×¥í¥°¥é¥à¤Ç¤¢¤ë¡£#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/time.h> #include <sys/types.h> #include <string.h> #include <signal.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> static int forward_port; #undef max #define max(x,y) ((x) > (y) ? (x) : (y)) static int listen_socket(int listen_port) { struct sockaddr_in a; int s; int yes; if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); return -1; } yes = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &yes, sizeof(yes)) < 0) { perror("setsockopt"); close(s); return -1; } memset(&a, 0, sizeof(a)); a.sin_port = htons(listen_port); a.sin_family = AF_INET; if (bind(s, (struct sockaddr *) &a, sizeof(a)) < 0) { perror("bind"); close(s); return -1; } printf("accepting connections on port %d\n", listen_port); listen(s, 10); return s; } static int connect_socket(int connect_port, char *address) { struct sockaddr_in a; int s; if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); close(s); return -1; } memset(&a, 0, sizeof(a)); a.sin_port = htons(connect_port); a.sin_family = AF_INET; if (!inet_aton(address, (struct in_addr *) &a.sin_addr.s_addr)) { perror("bad IP address format"); close(s); return -1; } if (connect(s, (struct sockaddr *) &a, sizeof(a)) < 0) { perror("connect()"); shutdown(s, SHUT_RDWR); close(s); return -1; } return s; } #define SHUT_FD1 { \ if (fd1 >= 0) { \ shutdown(fd1, SHUT_RDWR); \ close(fd1); \ fd1 = -1; \ } \ } #define SHUT_FD2 { \ if (fd2 >= 0) { \ shutdown(fd2, SHUT_RDWR); \ close(fd2); \ fd2 = -1; \ } \ } #define BUF_SIZE 1024 int main(int argc, char **argv) { int h; int fd1 = -1, fd2 = -1; char buf1[BUF_SIZE], buf2[BUF_SIZE]; int buf1_avail, buf1_written; int buf2_avail, buf2_written; if (argc != 4) { fprintf(stderr, "Usage\n\tfwd <listen-port> " "<forward-to-port> <forward-to-ip-address>\n"); exit(EXIT_FAILURE); } signal(SIGPIPE, SIG_IGN); forward_port = atoi(argv[2]); h = listen_socket(atoi(argv[1])); if (h < 0) exit(EXIT_FAILURE); for (;;) { int r, nfds = 0; fd_set rd, wr, er; FD_ZERO(&rd); FD_ZERO(&wr); FD_ZERO(&er); FD_SET(h, &rd); nfds = max(nfds, h); if (fd1 > 0 && buf1_avail < BUF_SIZE) { FD_SET(fd1, &rd); nfds = max(nfds, fd1); } if (fd2 > 0 && buf2_avail < BUF_SIZE) { FD_SET(fd2, &rd); nfds = max(nfds, fd2); } if (fd1 > 0 && buf2_avail - buf2_written > 0) { FD_SET(fd1, &wr); nfds = max(nfds, fd1); } if (fd2 > 0 && buf1_avail - buf1_written > 0) { FD_SET(fd2, &wr); nfds = max(nfds, fd2); } if (fd1 > 0) { FD_SET(fd1, &er); nfds = max(nfds, fd1); } if (fd2 > 0) { FD_SET(fd2, &er); nfds = max(nfds, fd2); } r = select(nfds + 1, &rd, &wr, &er, NULL); if (r == -1 && errno == EINTR) continue; if (r < 0) { perror("select()"); exit(EXIT_FAILURE); } if (FD_ISSET(h, &rd)) { unsigned int l; struct sockaddr_in client_address; memset(&client_address, 0, l = sizeof(client_address)); r = accept(h, (struct sockaddr *) &client_address, &l); if (r < 0) { perror("accept()"); } else { SHUT_FD1; SHUT_FD2; buf1_avail = buf1_written = 0; buf2_avail = buf2_written = 0; fd1 = r; fd2 = connect_socket(forward_port, argv[3]); if (fd2 < 0) { SHUT_FD1; } else printf("connect from %s\n", inet_ntoa(client_address.sin_addr)); } } /* NB: read oob data before normal reads */ if (fd1 > 0) if (FD_ISSET(fd1, &er)) { char c; errno = 0; r = recv(fd1, &c, 1, MSG_OOB); if (r < 1) { SHUT_FD1; } else send(fd2, &c, 1, MSG_OOB); } if (fd2 > 0) if (FD_ISSET(fd2, &er)) { char c; errno = 0; r = recv(fd2, &c, 1, MSG_OOB); if (r < 1) { SHUT_FD1; } else send(fd1, &c, 1, MSG_OOB); } if (fd1 > 0) if (FD_ISSET(fd1, &rd)) { r = read(fd1, buf1 + buf1_avail, BUF_SIZE - buf1_avail); if (r < 1) { SHUT_FD1; } else buf1_avail += r; } if (fd2 > 0) if (FD_ISSET(fd2, &rd)) { r = read(fd2, buf2 + buf2_avail, BUF_SIZE - buf2_avail); if (r < 1) { SHUT_FD2; } else buf2_avail += r; } if (fd1 > 0) if (FD_ISSET(fd1, &wr)) { r = write(fd1, buf2 + buf2_written, buf2_avail - buf2_written); if (r < 1) { SHUT_FD1; } else buf2_written += r; } if (fd2 > 0) if (FD_ISSET(fd2, &wr)) { r = write(fd2, buf1 + buf1_written, buf1_avail - buf1_written); if (r < 1) { SHUT_FD2; } else buf1_written += r; } /* check if write data has caught read data */ if (buf1_written == buf1_avail) buf1_written = buf1_avail = 0; if (buf2_written == buf2_avail) buf2_written = buf2_avail = 0; /* one side has closed the connection, keep writing to the other side until empty */ if (fd1 < 0 && buf1_avail - buf1_written == 0) { SHUT_FD2; } if (fd2 < 0 && buf2_avail - buf2_written == 0) { SHUT_FD1; } } exit(EXIT_SUCCESS); }
¾åµ¤Î¥×¥í¥°¥é¥à¤Ï¡¢¤Û¤È¤ó¤É¤Î¼ïÎà¤Î TCP Àܳ¤ò¥Õ¥©¥ï¡¼¥É¤¹¤ë¡£ telnet ¥µ¡¼¥Ð¤Ë¤è¤Ã¤ÆÃæ·Ñ¤µ¤ì¤ë OOB ¥·¥°¥Ê¥ë¥Ç¡¼¥¿¤â°·¤¨¤ë¡£ ¤³¤Î¥×¥í¥°¥é¥à¤Ï¡¢¥Ç¡¼¥¿¥Õ¥í¡¼¤òÁÐÊý¸þ¤ËƱ»þ¤ËÁ÷¤ë¤È¤¤¤¦¡¢ ¤ä¤ä¤³¤·¤¤ÌäÂê¤â½èÍý¤Ç¤¤ë¡£ fork(2) ¥³¡¼¥ë¤ò»È¤Ã¤Æ¡¢³Æ¥¹¥È¥ê¡¼¥à¤´¤È¤ËÀìÍѤΥ¹¥ì¥Ã¥É¤òÍѤ¤¤ë¤Û¤¦¤¬¸úΨŪ¤À¡¢ ¤È¤¤¤¦¿Í¤â¤¤¤ë¤«¤â¤·¤ì¤Ê¤¤¡£¤·¤«¤·¡¢¤³¤ì¤Ï¹Í¤¨¤Æ¤¤¤ë¤è¤ê¤º¤Ã¤È¤ä¤ä¤³¤·¤¤¡£ ¤¢¤ë¤¤¤Ï¡¢ ioctl(2) ¥³¡¼¥ë¤ò»È¤Ã¤ÆÈó¥Ö¥í¥Ã¥¯ I/O ¤ò¥»¥Ã¥È¤¹¤ì¤ÐÎɤ¤¡¢¤È¤¤¤¦¥¢¥¤¥Ç¥¢¤â¤¢¤ë¤À¤í¤¦¡£ ¤³¤ì¤Ë¤â¼ÂºÝ¤Ë¤ÏÌäÂ꤬¤¢¤ê¡¢¥¿¥¤¥à¥¢¥¦¥È¤¬Èó¸úΨŪ¤Ëµ¯¤³¤Ã¤Æ¤·¤Þ¤¦¡£
¤³¤Î¥×¥í¥°¥é¥à¤Ï°ìÅ٤ˤҤȤİʾå¤ÎƱ»þÀܳ¤ò°·¤¦¤³¤È¤Ï¤Ç¤¤Ê¤¤¤¬¡¢ ¤½¤ÎÍͤ˳ÈÄ¥¤¹¤ë¤Î¤Ï´Êñ¤Ç¡¢¥Ð¥Ã¥Õ¥¡¤Î¥ê¥ó¥¯¥ê¥¹¥È¤ò (Àܳ¤´¤È¤Ë¤Ò¤È¤Ä¤º¤Ä) »È¤¨¤Ð¤è¤¤¡£ ¸½»þÅÀ¤Î¤â¤Î¤Ç¤Ï¡¢¿·¤·¤¤Àܳ¤¬¤¯¤ë¤È¸Å¤¤Àܳ¤ÏÍî¤Á¤Æ¤·¤Þ¤¦¡£
´ØÏ¢¹àÌÜ
accept(2), connect(2), ioctl(2), poll(2), read(2), recv(2), select(2), send(2), sigprocmask(2), write(2), sigaddset(3), sigdelset(3), sigemptyset(3), sigfillset(3), sigismember(3), epoll(7)Contenus ©2006-2024 Benjamin Poulain
Design ©2006-2024 Maxime Vantorre