ºìÁªLinuxÃÅ»§
Linux°ïÖú

I/O¸´ÓÃ

·¢²¼Ê±¼ä:2008-10-28 13:38:38À´Ô´:ºìÁª×÷Õß:jerry520
I/O Ä£ÐÍ
Îå¸ö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 /* for OPEN_MAX */
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 */
}
}
}
}
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 2 ÌõÆÀÂÛ

  1. yeung ÓÚ 2008-10-29 19:04:16·¢±í:

    (e:e2s (e:e2s

  2. Yohcc ÓÚ 2008-10-28 15:21:34·¢±í:

    ·¹ý