Îå¸öI/OÄ£ÐÍ
×èÈûI/O
·Ç×èÈûI/O
I/O¸´ÓÃ(selectºÍpoll)
ÐźÅÇý¶¯I/O(SIGIO)
Òì²½I£¯O
×èÈû I/OÄ£ÐÍ
½ø³Ìµ÷ÓÃrecvfrom£¬´Ëϵͳµ÷ÓÃÖ±µ½Êý¾Ý±¨µ½´ïÇÒ¿½±´µ½Ó¦Óûº³åÇø»òÊdzö´í²Å·µ»Ø¡£×î³£¼ûµÄ´íÎóÊÇϵͳµ÷Óñ»ÐźÅÖжϣ¬½ø³Ì×èÈûµÄÕû¶Îʱ¼äÊÇÖ¸´Óµ÷ÓÃrecvfrom¿ªÊ¼µ½Ëü·µ»ØµÄÕâ¶Îʱ¼ä£¬µ±½ø³Ì·µ»Ø³É¹¦Ö¸Ê¾Ê±£¬Ó¦Óýø³Ì¿ªÊ¼´¦ÀíÊý¾Ý±¨¡£
·Ç×èÈû·½Ê½
µ±ÇëÇóµÄI/O²Ù×÷²»ÄÜÍê³Éʱ£¬²»Èýø³Ì˯Ãߣ¬¶øÓ¦·µ»ØÒ»¸ö´íÎó¡£ Ç°Èý´Îµ÷ÓÃrecvfromʱÈÔÎÞÊý¾Ý·µ»Ø£¬Òò´ËÄÚºËÁ¢¼´·µ»ØÒ»¸ö´íÎó¡£µÚËĴε÷ÓÃrecvfromʱ£¬Êý¾Ý±¨ÒÑ×¼±¸ºÃ£¬±»¿½±´µ½Ó¦Óûº³åÇø, recvfrom·µ»Ø³É¹¦Ö¸Ê¾£¬½Ó×Å´¦ÀíÊý¾Ý¡£ ´Ë¹ý³Ì³ÆΪÂÖѯ(polling)¡£Õâ¶ÔCPUʱ¼äÊǼ«´óµÄÀË·Ñ¡£
I/O¸´ÓÃÄ£ÐÍ
µ÷ÓÃselect»òpoll£¬ÔÚÕâÁ½¸öϵͳµ÷ÓÃÖеÄijһ¸öÉÏ×èÈû£¬¶ø²»ÊÇ×èÈûÓÚÕæÕýI/Oϵͳµ÷Óᣠ×èÈûÓÚselectµ÷Ó㬵ȴýÊý¾Ý±¨Ì׽ӿڿɶÁ¡£µ±select·µ»ØÌ׽ӿڿɶÁÌõ¼þʱ£¬µ÷ÓÃrecevfrom½«Êý¾Ý±¨¿½±´µ½Ó¦Óûº³åÇøÖС£
ÐźÅÇý¶¯I/OÄ£ÐÍ
Ì×½Ó¿ÚÆô¶¯ÐźÅÇý¶¯I/O, ²¢Í¨¹ýϵͳµ÷ÓÃsigaction°²×°Ò»¸öÐźŴ¦Àí³ÌÐò¡£´Ëϵͳµ÷ÓÃÁ¢¼´·µ»Ø£¬½ø³Ì¼ÌÐø¹¤×÷£¬ËüÊÇ·Ç×èÈûµÄ¡£
µ±Êý¾Ý±¨×¼±¸ºÃ±»¶Áʱ£¬¾ÍΪ¸Ã½ø³ÌÉú³ÉÒ»¸öSIGIOÐźš£
Ëæ¼´¿ÉÒÔÔÚÐźŴ¦Àí³ÌÐòÖе÷ÓÃrecvfromÀ´¶ÁÊý¾Ý±¨£¬¾®Í¨ÖªÖ÷Ñ»·Êý¾ÝÒÑ×¼±¸ºÃ±»´¦ÀíÖС£Ò²¿ÉÒÔ֪ͨÖ÷Ñ»·£¬ÈÃËüÀ´¶ÁÊý¾Ý±¨¡£
Òì²½I/OÄ£ÐÍ
ÈÃÄÚºËÆô¶¯²Ù×÷£¬²¢ÔÚÕû¸ö²Ù×÷Íê³Éºó(°üÀ¨½«Êý¾Ý´ÓÄں˿½±´µ½Óû§×Ô¼ºµÄ»º³åÇø)֪ͨÓû§¡£
ÐźÅÇý¶¯I/O£ºÓÉÄÚºË֪ͨÎÒÃǺÎʱ¿ÉÒÔÆô¶¯Ò»¸öI/O²Ù×÷£¬
Òì²½I/OÄ£ÐÍ£ºÓÉÄÚºË֪ͨÎÒÃÇI/O²Ù×÷ºÎʱÍê³É¡£
--------------------------------------------------------------------------------
select º¯Êý
ÔÊÐí½ø³ÌָʾÄں˵ȴý¶à¸öʼþÖеÄÈÎÒ»¸ö·¢Éú£¬²¢½öÔÚÒ»¸ö»ò¶à¸öʼþ·¢Éú»ò¾¹ýijָ¶¨µÄʱ¼äºó²Å»½Ðѽø³Ì¡£
×÷Ϊһ¸öÀý×Ó£¬ÎÒÃÇ¿ÉÒÔµ÷Óú¯Êýselect²¢Í¨ÖªÄں˽öÔÚÏÂÁÐÇé¿ö·¢Éúʱ²Å·µ»Ø
¼¯ºÏ{1£¬4£¬5}ÖеÄÈκα¨Êö×Ö×¼±¸ºÃ¶Á
¼¯ºÏ{2£¬7}µÄÈκÎÃèÊö×Ö×¼±¸ºÃд
¼¯ºÏ{1£¬4}ÖеÄÈκÎÃèÊö×ÖÓÐÒì³£Ìõ¼þ´ý´¦Àí
ÒѾ¹ýÁË10£®2Ãë
֪ͨÄÚºËÎÒÃǶÔÄÄЩÃèÊö×Ö¸ÐÐËȤ(¶Á¡¢Ð´»òÒì³£Ìõ¼þ)ÒÔ¼°µÈ´ý¶à³¤Ê±¼ä¡£
ÃèÊö×Ö²»ÊÜÏÞÓÚÌ×½Ó¿Ú£ºÈκÎÃèÊö×Ö£¨ÀýÈçÎļþÃèÊö×Ö£©¶¼¿ÉÓÃselectÀ´²âÊÔ¡£
select ¶¨Òå
int select(int maxfdp1,fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval *timeout);
maxfdp1 £º ÃèÊö×Ö×î´óÖµ
readset £º ¶ÁÃèÊö×Ö¼¯
writeset £º дÃèÊö×Ö¼¯
exceptset £º Òì³£Ìõ¼þµÄÃèÊö×Ö¼¯
timeout £º µÈ´ýʱ¼ä
readset, writesetºÍexceptset
ÈÃÄں˲âÊÔ¶Á¡¢Ð´ºÍÒì³£Ìõ¼þËùÐèµÄÃèÊö×Ö¡£
ΪÕâÈý¸ö²ÎÊýµÄÿһ¸öÖ¸¶¨Ò»¸ö»ò¶à¸öÃèÊö×ÖÖµ
ÃèÊö×Ö¼¯£¬ÊÇÒ»¸öÕûÊýÊý×飬ÿ¸öÊýÖеÄÿһλ¶ÔÓ¦Ò»¸öÃèÊö×Ö¡£
Êý×éµÄµÚÒ»¸öÔªËضÔÓ¦ÓÚÃèÊö×Ö0-31£¬
Êý×黧µÄµÚ¶þ¸öÔªËضÔÓ¦ÓÚÃèÊö×Ö32--63¡£
Àý×Ó£º
fd_set rset; //¶¨ÒåÃèÊö×Ö¼¯Êý¾ÝÀàÐÍ
FD_ZERO (&rset); //¶ÔÃèÊö×Ö¼¯³õʼ»¯
FD_SET(1, &rset); //´ò¿ªÃèÊö×ֵĵÚ1λ
FD_SET(4, &rset£© // //´ò¿ªÃèÊö×ֵĵÚ4λ
......
FD_ISSET(4, &rest) //²âÊÔÃèÊö×ֵĵÚ4λ
FD_CLR(4, &rset£© // //¹Ø±ÕÃèÊö×ֵĵÚ4λ
readset Ì×½Ó¿Ú×¼±¸ºÃ¶Á
Ì×½Ó¿Ú½ÓÊÕ»º³åÇøÖеÄÊý¾Ý×Ö½ÚÊý>=
Ì×½Ó¿Ú½ÓÊÕ»º³åÇøµÍ³±Ï޶ȵĵ±Ç°Öµ
Á¬½ÓµÄ¶ÁÕâÒ»°ë¹Ø±Õ(½ÓÊÕÁËFINµÄTCPÁ¬½Ó)
Ì×½Ó¿ÚÊÇÒ»¸ö¼àÌýÌ×½Ó¿Úµ©ÒÑÍê³ÉµÄÁ¬½ÓÊýΪ·Ç0¡£
ÓÐÒ»¸öÌ×½Ó¿Ú´íÎó´ý´¦Àí¡£
writeset Ì×½Ó¿Ú×¼±¸ºÃд
Ì×½Ó¿Ú·¢ËÍ»º³åÇøÖеĿÉÓÿռä×Ö½ÚÊý´ó¸ÉµÈÓÚÌ×½Ó¿Ú·¢ËÍ»º³åÇøµÍ³±Ï޶ȵÄ
µ±Ç°Öµ£¬ÇÒ»òÕß(i)Ì×½Ó¿ÚÒÑÁ¬½Ó£¬»òÕß(i)Ì×½Ó¿Ú²»ÒªÇóÁ¬½Ó
Á¬½ÓµÄдÕâÒ»°ë¹Ø±Õ¡£¶ÔÕâÑùµÄÌ×½Ó¿ÚµÄд²Ù×÷½«²úÉúÐÅSIGPIPE¡£
ÓÐÒ»¸öÌ×½Ó¿Ú´íÎó´ý´¦Àí¡£¶ÔÕâÑùµÄÌ×½Ó¿ÚµÄд²Ù×÷½«²»×èÈûÇÒ·µ»ØÒ»¸ö´íÎó(Ò»1)
exceptsetÒì³£Ìõ¼þ´ý´¦Àí
Èç¹ûÒ»¸öÌ×½Ó¿Ú´æÔÚ´øÍâÊý¾Ý»òÕßÈÔ´¦ÓÚ´øÍâ±ê¼Ç£¬ÄÇËüÓÐÒì³£Ìõ¼þ´ý´¦Àí¡£
´øÍâÊý¾Ý(out--of--band data)£¬ÓÐʱҲ³ÆΪ¼ÓËÙÊý¾Ý(expedited data)£¬
ÊÇÖ¸Á¬½ÓË«·½ÖеÄÒ»·½·¢ÉúÖØÒªÊÂÇ飬ÏëҪѸËÙµØ֪ͨ¶Ô·½¡£
ÕâÖÖ֪ͨÔÚÒѾÅŶӵȴý·¢Ë͵ÄÈκΡ°ÆÕͨ¡±(ÓÐʱ³ÆΪ¡°´øÄÚ¡±)Êý¾Ý֮ǰ·¢ËÍ¡£
´øÍâÊý¾ÝÉè¼ÆΪ±ÈÆÕͨÊý¾ÝÓиü¸ßµÄÓÅÏȼ¶¡£
´øÍâÊý¾ÝÊÇÓ³Éäµ½ÏÖÓеÄÁ¬½ÓÖеģ¬¶ø²»ÊÇÔÚ¿Í»§»úºÍ·þÎñÆ÷¼äÔÙÓÃÒ»¸öÁ¬½Ó¡£
×î´óÃèÊö×Ö maxfdp1
µ±select¸Õ¿ªÊ¼Éè¼Æʱ£¬²Ù×÷ϵͳ³£¶Ôÿ¸ö½ø³Ì¿ÉÓõÄ×î´óÃèÊö×ÖÊýÉÏÏÞ×÷³ö
ÏÞÖÆ(4.2BSDµÄÏÞÖÆΪ31)£¬selectÒ²¾ÍÓÃÏàͬµÄÏÞÖÆÖµ¡£
unix°æ±¾¶Ôÿ¸ö½ø³ÌµÄÃèÊö×ÖÊý¸ù±¾²»×÷ÏÞÖÆ (½öÊÜÏÞÓÚÄÚ´æÁ¿ºÍ¹ÜÀíÐÔÏÞÖÆ)£¬
#include
#DEFINE FD_SETSIZE 256
--------------------------------------------------------------------------------
str_cli º¯ÊýµÄÐÞ¶©°æ
·þÎñÆ÷½ø³ÌÒ»ÖÕÖ¹¿Í»§¾ÍÄÜÂíÉϵõ½Í¨Öª
ÔçÆÚ°æ±¾µÄÎÊÌâ¾ÍÔÚÓÚµ±Ì×½Ó¿ÚÉÏ·¢ÉúÁËijЩʼþʱ£¬¿Í»§¿ÉÄÜ×èÈûÓÚfgetsµ÷Óã¬
а汾Ôò×èÈûÓÚselectµ÷Ó㺵ȴý±ê×¼ÊäÈ룬µÈ´ýÌ׽ӿڿɶÁ¡£
//¾ÉµÄ»ØÉä·þÎñÆ÷¿Í»§¶Ëmain³ÌÐò
#include ¡°unp.h¡° //°üº¬Í·Îļþ
int main(int argc, char **argv) //argvÊÇÃüÁîÐеĵڶþ¸ö²ÎÊý
{ int sockfd; //Ì×½Ó¿ÚÃèÊö×Ö
struct sockaddr_in servaddr; //IPv4µØÖ·½á¹¹
if (argc != 2) //ÃüÁîÐÐÒªÓеڶþ¸ö²ÎÊý£¨·þÎñÆ÷µØÖ·£©
err_quit("usage: tcpcli
sockfd = Socket(AF_INET, SOCK_STREAM, 0); //
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
str_cli(stdin, sockfd); /* do it all */
exit(0);
}
//str_cli
#include "unp.h"
void str_cli ( FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
while (Fgets ( sendline, MAXLINE, fp) ! = NULL) {
Writen( sockfd, sendline, strlen(sendline) );
if ( Readline ( sockfd, recvline, MAXLINE ) = = 0)
err_quit("str_cli: server terminated prematurely");
Fputs(recvline, stdout);
}
}
¶ÔÌ׽ӿڵĴ¦Àí
¶Ô·½TCP·¢ËÍÊý¾Ý£¬Ì׽ӿھͱäΪ¿É¶ÁÇÒread·µ»Ø´óÓÚ0
¶Ô·½TCP·¢ËÍÒ»¸öFIN(¶Ô·½½ø³ÌÖÕÖ¹)£¬Ì׽ӿھͱäΪ¿É¶ÁÇÒread·µ»Ø0(Îļþ½áÊø)¡£
¶Ô·½TCP·¢ËÍÒ»¸öRST (¶Ô·½Ö÷»ú±ÀÀ£²¢ÖØÐÂÆô¶¯)£¬Ì×½Ó¿Ú±äΪ¿É¶ÁÇÒ·µ»Ø-1
#include "unp.h"
void str_cli(FILE *fp, int sockfd)
{ int maxfdp1; //×î´óÃèÊö×Ö
fd_set rset; //ÃèÊö×Ö¼¯
char sendline[MAXLINE], recvline[MAXLINE];
FD_ZERO(&rset); //ÃèÊö×Ö¼¯ÇåÁ㣨¿Õ¼¯£©
for ( ; ; ) {
FD_SET(fileno(fp), &rset); //´ò¿ªÎļþÃèÊö×ֵIJâÊÔ
FD_SET(sockfd, &rset); // //´ò¿ªÌ×½Ó¿ÚÃèÊö×ֵIJâÊÔ
maxfdp1 = max(fileno(fp), sockfd) + 1; //»ñµÃ×î´óÃèÊö×Ö
Select(maxfdp1, &rset, NULL, NULL, NULL); //¶ÔÊÇ·ñ¿É¶Á½øÐвâÊÔ
if (FD_ISSET(sockfd, &rset)) { //Èç¹ûÌ׽ӿڿɶÁ
if (Readline(sockfd, recvline, MAXLINE) = = 0) //¶ÁÈëÒ»ÐÐ
err_quit(¡°str_cli: server termi. premat..¡±); //¶Ô·½ÖÕֹʱÍ˳ö
Fputs(recvline, stdout); //дµ½±ê×¼Êä³ö
}
if (FD_ISSET(fileno(fp), &rset)) { //Èç¹û±ê×¼ÊäÈë¿É¶Á
if (Fgets(sendline, MAXLINE, fp) == NULL) //¶ÁÈëÒ»ÐÐ
return; // Óöµ½^DʱÍ˳ö×Ó³ÌÐò
Writen(sockfd, sendline, strlen(sendline)); //дÈëÌ×½Ó¿Ú
}
}
}
--------------------------------------------------------------------------------
shutdown º¯Êý
closeÓÐÁ½¸öÏÞÖÆ¿ÉÓɺ¯ÊýshutdownÀ´±ÜÃâ:
close½«ÃèÊö×ֵķÃÎʼÆÊý¼õ1£¬½öÔڴ˼ÆÊýΪ0ʱ²Å¹Ø±ÕÌ×½Ó¿Ú
shutdown¿É¼¤·¢TCPµÄÕý³£Á¬½ÓÖÕÖ¹ÐòÁÐ, ¶ø²»¹Ü·ÃÎʼÆÊý¡£
closeÖÕÖ¹ÁËÊý¾Ý´«Ë͵ÄÁ½¸ö·½Ïò£º¶ÁºÍд¡£
shutdownÖÕÖ¹µÄÊý¾Ý´«Ë͵ÄÁ½¸ö·½Ïò£º¶ÁºÍд, »òÆäÖÐÈÎÒ»·½Ïò£º¶Á»òд
¶¨Ò壺
int shutdown( int sockfd, int howto) ;
howtoÑ¡Ïî:
SHUT_RD ¹Ø±ÕÁ¬½ÓµÄ¶ÁÒ»°ë
SHUT_WR ¹Ø±ÕÁ¬½ÓµÄдÕâÒ»°ë
SHUT_RDWR ¹Ø±ÕÁ¬½Ó¶Á¶ÁºÍд
--------------------------------------------------------------------------------
str_cliº¯Êý£¨ÔÙÐÞ¶©£©
void str_cli(FILE *fp, int sockfd)
{ int maxfdp1, stdineof ; fd_set rset;
char sendline[MAXLINE], recvline[MAXLINE];
stdineof=0; FD_ZERO(&rset);
for ( ; ; ) {
if (stdineof == 0) FD_SET(fileno(fp), &rset);
FD_SET(sockfd, &rset);
maxfdp1 = max(fileno(fp), sockfd) + 1;
Select(maxfdp1, &rset, NULL, NULL, NULL);
if (FD_ISSET(sockfd, &rset)) { /* socket is readable */
if (Readline(sockfd, recvline, MAXLINE) == 0) {
if (stdineof == 1) return; /* normal termination */
else err_quit(¡°str_cli: server ERR. "); }
Fputs(recvline, stdout);
}
if (FD_ISSET(fileno(fp), &rset)) { /* input is readable */
if (Fgets(sendline, MAXLINE, fp) == NULL) {
stdineof = 1;
Shutdown(sockfd, SHUT_WR); /* send FIN */
FD_CLR(fileno(fp), &rset);
continue; }
Writen(sockfd, sendline, strlen(sendline));
} } }
--------------------------------------------------------------------------------
TCP»ØÉä·þÎñÆ÷³ÌÐò£¨ÐÞ¶©°æ£©
ʹÓÃselectÀ´´¦ÀíÈÎÒâÊýÄ¿µÄ¿Í»§µÄµ¥½ø³Ì³ÌÐò
²»ÎªÃ¿¸ö¿Í»§ÅÉÉúÒ»¸ö×Ó½ø³Ì£¬±ÜÃâÁË´´½¨Ò»¸öнø³ÌµÄËùÓпªÏú¡£
¼àÌýÌ×½Ó¿Ú
·þÎñÆ÷ֻά»¤Ò»¸ö¶ÁÃèÊö×Ö¼¯
ÃèÊö×Ö0¡¢1ºÍ2·Ö±ð±»ÉèÖÃΪ±ê×¼ÊäÈë¡¢±ê×¼Êä³öºÍ±ê×¼´íÎóÊä³ö
¼àÌýÌ׽ӿڵĵÚÒ»¸ö¿ÉÓõÄÃèÊö×ÖÊÇ3¡£
ÓëµÚÒ»¸ö¿Í»§½¨Á¢Á¬½Ó
¼àÌýÃèÊö×Ö±äΪ¿É¶Á£¬ÓÚÊÇ·þÎñÆ÷µ÷ÓÃaccept¡£
ÓÉaccept·µ»ØµÄеÄÒÑÁ¬½ÓÃèÊö×Ö½«ÊÇ4¡£
µÚÒ»¸ö¿Í»§ÖÕÖ¹Óë·þÎñÆ÷µÄÁ¬½Ó
¿Í»§TCP·¢ËÍÒ»¸öFIN£¬ÕâʹµÃ·þÎñÆ÷ÖеÄÃèÊö×Ö4±äΪ¿É¶Á¡£
µ±·þÎñÆ÷¶Á´ËÒÑÁ¬½ÓÌ×½Ó¿Úʱ£¬readline·µ»Ø0¡£
¹Ø±Õ´ËÌ×½Ó¿Ú²¢ÏàÓ¦µØ¸üÐÂÊý¾Ý½á¹¹£¬Êý×éÔªËØclient[0]]µÄÖµÖÃΪһ1£¬
ÃèÊö×Ö¼¯ÖеÄÃèÊö×Ö4±»ÖÃΪ0,maxfdµÄֵûÓиı䡣
//Ô´³ÌÐò
int main(int argc, char **argv)
{ int i, maxi, maxfd, listenfd, connfd, sockfd;
int nready, client[FD_SETSIZE];
ssize_t n;
fd_set rset, allset;
char line[MAXLINE];
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
maxfd = listenfd; /* initialize */
maxi = -1; /* index into client[] array */
for (i = 0; i < FD_SETSIZE; i++)
client[i] = -1; /* -1 indicates available entry */
FD_ZERO(&allset);
FD_SET(listenfd, &allset);
for ( ; ; ) {
rset = allset; /* structure assignment */
nready = Select(maxfd+1, &rset, NULL, NULL, NULL);
if (FD_ISSET(listenfd, &rset)) { /* new client connection */
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
for (i = 0; i < FD_SETSIZE; i++)
if (client[i] < 0) {
client[i] = connfd; /* save descriptor */
break
}
if (i == FD_SETSIZE) err_quit("too many clients");
FD_SET(connfd, &allset); /* add new descriptor to set */
if (connfd > maxfd) maxfd = connfd; /* for select */
if (i > maxi) maxi = i; /* max index in client[] array */
if (--nready <= 0) continue; /* no more readable descriptors */
}
for (i = 0; i <= maxi; i++) { /* check all clients for data */
if ( (sockfd = client[i]) < 0) continue;
if (FD_ISSET(sockfd, &rset)) {
if ( (n = Readline(sockfd, line, MAXLINE)) == 0) {
/*4connection closed by client */
Close(sockfd);
FD_CLR(sockfd, &allset);
client[i] = -1;
}
else Writen(sockfd, line, n);
if (--nready <= 0) break; /* no more readable descriptors */
}
}
} //end of for loop
} //end of main
--------------------------------------------------------------------------------
poll º¯Êý
ÔÐÍ:
int poll (struct pollfd *fdarray, unsigned long nfds, int timeout )
µÚÒ»¸ö²ÎÊýÊÇÖ¸Ïò½á¹¹Êý×éµÚÒ»¸öÔªËصÄÖ¸Õ룺
struct pollfd{
int fd; // descriptor
short events // events of interest on fd
short revents // events that occured on fd
}
µÚ¶þ¸ö²ÎÊýÊÇÌ×½Ó×Ö¸öÊý£¬µÚÈý¸ö²ÎÊýÊǵȴýʱ¼ä
--------------------------------------------------------------------------------
TCP»ØÉä·þÎñÆ÷³ÌÐò(ÔÙÐÞ¶©£©
ÓÃpoll¶ø²»ÊÇÓÃselectÀ´ÖØд»ØÉä·þÎñÆ÷³ÌÐò¡£
ÔÚselect°æ±¾ÖУ¬±ØÐë·ÖÅäÒ»¸öclientÊý×éÒÔ¼°Ò»¸öÃûΪrsetµÄÃèÊö×Ö¼¯¡£
ʹÓÃpollʱ, ±ØÐë·ÖÅäÒ»¸öpoll½á¹¹µÄÊý×éÀ´Î¬»¤¿Í»§ÐÅÏ¢£¬¶ø²»ÊÇ·ÖÅäÁíÒ»¸öÊý×é¡£
ÓëselectÖд¦ÀíÊý×éclientÏàͬµÄ·½·¨, ´¦Àí´ËÊý×éµÄfd³ÉÔ±£¬ÖµÒ»1±íʾÌõĿδÓã¬
·ñÔò¼´ÎªÃèÊö×ÖÖµ¡£
´«µÝ¸øpollµÄpollfd½á¹¹Êý×éÖеÄÈκÎN³ÉԱΪ¸ºÖµµÄÌõÄ¿¶¼ÊDZ»ºöÂԵġ£
//Ô´³ÌÐò£º
#include "unp.h"
#include
int main(int argc, char **argv)
{
int i, maxi, listenfd, connfd, sockfd;
int nready; ssize_t n;
char line[MAXLINE];
socklen_t clilen;
struct pollfd client[OPEN_MAX];
struct sockaddr_in cliaddr, servaddr;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
client[0].fd = listenfd;
client[0].events = POLLRDNORM;
for (i = 1; i < OPEN_MAX; i++)
client[i].fd = -1; /* -1 indicates available entry */
maxi = 0;
for ( ; ; ) {
nready = Poll(client, maxi+1, INFTIM);
/* new client connection */
if (client[0].revents & POLLRDNORM) {
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
for (i = 1; i < OPEN_MAX; i++)
if (client[i].fd < 0) {
client[i].fd = connfd; // save descriptor
break;
}
if (i == OPEN_MAX)
err_quit("too many clients");
client[i].events = POLLRDNORM;
if (i > maxi)
maxi = i; /* max index in client[] array */
if (--nready <= 0)
continue; /* no more readable descriptors */
}
for (i = 1; i <= maxi; i++) { /* check all clients for data */
if ( (sockfd = client[i].fd) < 0) continue;
if (client[i].revents & (POLLRDNORM | POLLERR)) {
if ( (n = readline(sockfd, line, MAXLINE)) < 0) {
if (errno == ECONNRESET) {
/*4connection reset by client */
Close(sockfd);
client[i].fd = -1;
} else
err_sys("readline error");
} else if (n == 0) {
/*4connection closed by client */
Close(sockfd);
client[i].fd = -1;
} else
Writen(sockfd, line, n);
if (--nready <= 0)
break; /* no more readable descriptors */
}
}
}
}
yeung ÓÚ 2008-10-29 19:04:16·¢±í:
(e:e2s (e:e2s
Yohcc ÓÚ 2008-10-28 15:21:34·¢±í:
·¹ý