µ±Ç°Î»ÖãºLinux½Ì³Ì - Linux - Ò»¸ö¼òµ¥ÁÄÌìÊÒµÄÁ½ÖÖʵÏÖ (fcntl ºÍ select)

Ò»¸ö¼òµ¥ÁÄÌìÊÒµÄÁ½ÖÖʵÏÖ (fcntl ºÍ select)



        
    ÉîÈëUNIX±à³ÌÖ®Ò»

    eDOC¹¤×÷×é
    ¡¡

    ÔÚ»¥ÁªÍøÏ൱ÆÕ¼°µÄ½ñÌ죬ÔÚ»¥ÁªÍøÉÏÁÄÌì¶ÔºÜ¶à¡°Íø³æ¡±À´ËµÒѾ­ÊǼҳ£±ã·¹ÁË¡£ÁÄÌìÊÒ³ÌÐò¿ÉÒÔ˵ÊÇÍøÉÏ×î¼òµ¥µÄ¶àµãͨÐųÌÐò¡£ÁÄÌìÊÒµÄʵÏÖ·½·¨Óкܶ࣬µ«¶¼ÊÇÀûÓÃËùνµÄ¡°¶àÓû§¿Õ¼ä¡±À´¶ÔÐÅÏ¢½øÐн»»»£¬¾ßÓеäÐ͵Ķà·I/OµÄ¼Ü¹¹¡£Ò»¸ö¼òµ¥µÄÁÄÌìÊÒ, ´Ó³ÌÐòÔ±µÄ¹ÛµãÀ´¿´¾ÍÊÇÔÚ¶à¸öI/O¶ËµãÖ®¼äʵÏÖ¶à¶Ô¶àµÄͨÐÅ¡£Æä¼Ü¹¹ÈçͼһËùʾ¡£ÕâÑùµÄʵÏÖÔÚÓû§µÄÑÛÀï¾ÍÊÇÁÄÌìÊÒÄÚÈκÎÒ»¸öÈËÊäÈëÒ»¶Î×Ö·ûÖ®ºó,ÆäËûÓû§¶¼¿ÉÒԵõ½ÕâÒ»¾ä»°¡£ÕâÖÖ¡°¶àÓû§¿Õ¼ä¡±µÄ¼Ü¹¹ÔÚÆäËû¶àµãͨÐųÌÐòÖÐÓ¦Óõķdz£¹ã·º£¬ÆäºËÐľÍÊǶà·I/OͨÐÅ¡£¶à·I/OͨÐÅÓÖ±»³ÆΪI/O¶à·¸´Óã¨I/O Multiplexing£©Ò»°ã±»Ê¹ÓÃÔÚÒÔϵij¡ºÏ£º

    ¿Í»§³ÌÐòÐèҪͬʱ´¦Àí½»»¥Ê½µÄÊäÈëºÍͬ·þÎñÆ÷Ö®¼äµÄÍøÂçÁ¬½ÓʱÐèÒª´¦ÀíI/O¶à·¸´ÓÃÎÊÌ⣻
    ¿Í»§¶ËÐèҪͬʱ¶Ô¶à¸öÍøÂçÁ¬½Ó×÷³ö·´Ó¦£¨ÕâÖÖÇé¿öºÜÉÙ¼û£©£»

    TCP·þÎñÆ÷ÐèҪͬʱ´¦Àí´¦ÓÚ¼àÌý״̬ºÍ¶à¸öÁ¬½Ó״̬µÄsocket£»

    ·þÎñÆ÷ÐèÒª´¦Àí¶à¸öÍøÂçЭÒéµÄsocket;

    ·þÎñÆ÷ÐèҪͬʱ´¦Àí²»Í¬µÄÍøÂç·þÎñºÍЭÒé¡£
    ÁÄÌìÊÒËùÐèÒªÃæ¶ÔµÄÇé¿öÕýÊǵÚÒ»ºÍµÚÈýÁ½ÖÖÇé¿ö¡£ÎÒÃǽ«Í¨¹ýÔÚTCP/IPЭÒéÖ®ÉϽ¨Á¢Ò»¸ö¹¦Äܼòµ¥µÄÁÄÌìÊÒÈôó¼Ò¸ü¼ÓÁ˽â¶à·I/OÒÔ¼°ËüµÄʵÏÖ·½·¨¡£
    ÎÒÃÇÒªÌÖÂÛµÄÁÄÌìÊÒ¹¦Äܷdz£¼òµ¥, ¸ÐÐËȤµÄÅóÓÑ¿ÉÒÔ½«Æ书ÄÜÀ©Õ¹, ·¢Õ¹³ÉÒ»¸ö¹¦ÄܱȽÏÍêÕûµÄÁÄÌìÊÒ, Èç¼ÓÉÏÓû§ÈÏÖ¤, Óû§êdzÆ, ÃØÃÜÐÅÏ¢, semote µÈ¹¦ÄÜ.

    Ê×ÏÈËüÊÇÒ»¸ö client/server ½á¹¹µÄ³ÌÐò, Ê×ÏÈÆô¶¯ server, È»ºóÓû§Ê¹Óà client ½øÐÐÁ¬½Ó. client/server ½á¹¹µÄÓŵãÊÇËٶȿì, ȱµãÊǵ± server ½øÐиüÐÂʱ, client Ò²±ØÐè¸üÐÂ.

    ¡¡
    ÍøÂç³õʼ»¯

    ¡¡
    Ê×ÏÈÊdzõʼ»¯ server, ʹserver ½øÈë¼àÌý״̬: (ΪÁ˼ò½àÆð¼û,ÒÔÏÂÒýÓõijÌÐòÓëʵ¼Ê³ÌÐòÂÔÓгöÈë, ÏÂͬ)

    sockfd = socket( AF_INET,SOCK_STREAM, 0);
    // Ê×ÏȽ¨Á¢Ò»¸ö socket, ×åΪ AF_INET, ÀàÐÍΪ SOCK_STREAM.
    // AF_INET = ARPA Internet protocols ¼´Ê¹Óà TCP/IP ЭÒé×å
    // SOCK_STREAM ÀàÐÍÌṩÁË˳ÐòµÄ, ¿É¿¿µÄ, »ùÓÚ×Ö½ÚÁ÷µÄÈ«Ë«¹¤Á¬½Ó.
    // ÓÉÓÚ¸ÃЭÒé×åÖÐÖ»ÓÐÒ»¸öЭÒé, Òò´ËµÚÈý¸ö²ÎÊýΪ 0

    ¡¡

    bind( sockfd, ( struct sockaddr *)&serv_addr, sizeof( serv_addr));
    // ÔÙ½«Õâ¸ö socket Óëij¸öµØÖ·½øÐаó¶¨.
    // serv_addr °üÀ¨ sin_family = AF_INET ЭÒé×åͬ socket
    // sin_addr.s_addr = htonl( INADDR_ANY) server Ëù½ÓÊܵÄËùÓÐÆäËû
    // µØÖ·ÇëÇó½¨Á¢µÄÁ¬½Ó.
    // sin_port = htons( SERV_TCP_PORT) server Ëù¼àÌýµÄ¶Ë¿Ú
    // ÔÚ±¾³ÌÐòÖÐ, server µÄ IPºÍ¼àÌýµÄ¶Ë¿Ú¶¼´æ·ÅÔÚ config ÎļþÖÐ.

    listen( sockfd, MAX_CLIENT);
    // µØÖ·°ó¶¨Ö®ºó, server ½øÈë¼àÌý״̬.
    // MAX_CLIENT ÊÇ¿ÉÒÔͬʱ½¨Á¢Á¬½ÓµÄ client ×ÜÊý.

    server ½øÈë listen ״̬ºó, µÈ´ý client ½¨Á¢Á¬½Ó¡£

    Client¶ËÒª½¨Á¢Á¬½ÓÊ×ÏÈÒ²ÐèÒª³õʼ»¯Á¬½Ó£º

    sockfd = socket( AF_INET,SOCK_STREAM,0));
    // ͬÑùµÄ, client Ò²ÏȽ¨Á¢Ò»¸ö socket, Æä²ÎÊýÓë server Ïàͬ.

    connect( sockfd, ( struct sockaddr *)&serv_addr, sizeof( serv_addr));
    // client ʹÓà connect ½¨Á¢Ò»¸öÁ¬½Ó.
    // serv_addr ÖеıäÁ¿·Ö±ðÉèÖÃΪ:
    // sin_family = AF_INET ЭÒé×åͬ socket
    // sin_addr.s_addr = inet_addr( SERV_HOST_ADDR) µØַΪ server
    // ËùÔڵļÆËã»úµÄµØÖ·.
    // sin_port = htons( SERV_TCP_PORT) ¶Ë¿ÚΪ server ¼àÌýµÄ¶Ë¿Ú.

    µ± client ½¨Á¢ÐÂÁ¬½ÓµÄÇëÇó±»Ë͵½Server¶Ëʱ, server ʹÓà accept À´½ÓÊܸÃÁ¬½Ó:

    accept( sockfd, (struct sockaddr*)&cli_addr, &cli_len);
    // ÔÚº¯Êý·µ»Øʱ, cli_addr Öб£ÁôµÄÊǸÃÁ¬½Ó¶Ô·½µÄÐÅÏ¢
    // °üÀ¨¶Ô·½µÄ IP µØÖ·ºÍ¶Ô·½Ê¹ÓõĶ˿Ú.
    // accept ·µ»ØÒ»¸öеÄÎļþÃèÊö·û.

    ÔÚ server ½øÈë listen ״̬֮ºó, ÓÉÓÚÒÑÓжà¸öÓû§ÔÚÏߣ¬ËùÒÔ³ÌÐòÐèҪͬʱ¶ÔÕâЩÓû§½øÐвÙ×÷£¬²¢ÔÚËüÃÇÖ®¼äʵÏÖÐÅÏ¢½»»»¡£ÕâÔÚʵÏÖÉϳÆΪI/O¶à·¸´Óü¼Êõ¡£¶à·¸´ÓÃÒ»°ãÓÐÒÔϼ¸ÖÖ·½·¨£º

    ·Ç×èÈûͨÐÅ·½·¨£º½«Îļþ¹ÜµÀͨ¹ýfcntl()ÉèΪ·Ç×èÈûͨÐÅ·½Ê½£¬Ã¿¸ôÒ»¶Ëʱ¼ä¶ÔËûÃÇʵÐÐÒ»´ÎÂÖѯ£¬ÒÔÅжÏÊÇ·ñ¿ÉÒÔ½øÐжÁд²Ù×÷¡£ÕâÖÖ·½Ê½µÄȱµãÊÇ·ÑÓÃÌ«¸ß£¬´ó²¿·Ö×ÊÔ´ÀË·ÑÔÚÂÖѯÉÏ¡£
    ×Ó½ø³Ì·½·¨£ºÓ¦Óöà¸ö×Ó½ø³Ì£¬Ã¿Ò»¸ö¶ÔÒ»¸öµ¥¹¤×èÈû·½Ê½Í¨ÐÅ¡£ËùÓÐ×Ó½ø³Ìͨ¹ýIPCºÍ¸¸½ø³Ì½øÐÐͨÐÅ¡£¸¸½ø³ÌÕƹÜËùÓÐÐÅÏ¢¡£ÕâÖÖ·½Ê½µÄȱµãÊÇʵÏÖ¸´ÔÓ£¬¶øÇÒÓÉÓÚIPCÔÚ¸÷¸ö²Ù×÷ϵͳƽ̨Éϲ¢²»ÍêÈ«Ò»Ö£¬»áµ¼Ö¿ÉÒÆÖ²ÐÔ½µµÍ¡£
    ÐźÅÇý¶¯£¨SIGIO£©µÄÒì²½I/O·½·¨£ºÊ×ÏÈ£¬Òì²½I/OÊÇ»ùÓÚÐźŻúÖƵģ¬²¢²»¿É¿¿¡£Æä´Îµ¥Ò»µÄÐźŲ»×ãÒÔÌṩ¸ü¶àµÄÐÅÏ¢À´Ô´¡£»¹ÊÇÐèÒª¸¨ÖúÒÔÆäËûµÄÊֶΣ¬ÊµÏÖÉÏÓкܸߵÄÄѶȡ£
    select ()·½·¨£ºÔÚBSDÖÐÌṩÁËÒ»ÖÖ¿ÉÒÔ¶Ô¶à·I/O½øÐÐ×èÈûʽ²éѯµÄ·½·¨¡ª¡ªselect()¡£ËüÌṩͬʱ¶Ô¶à¸öI/OÃèÊö·û½øÐÐ×èÈûʽ²éѯµÄ·½·¨£¬ÀûÓÃËü£¬ÎÒÃÇ¿ÉÒԺܷ½±ãµÄʵÏֶ෸´Ó᣸ù¾ÝͳһUNIX¹æ·¶µÄЭÒé,POSIXÒ²²ÉÓÃÁËÕâÖÖ·½·¨£¬Òò´Ë£¬ÎÒÃÇ¿ÉÒÔÔÚ´ó¶àÊý²Ù×÷ϵͳÖÐʹÓÃselect·½·¨¡£
    ʹÓÃרÃŵÄI/O¶à·¸´ÓÃÆ÷£ºÔÚ¡°UNIX? SYSTEM V Programmer\s Guide: STREAMS¡±Ò»ÊéÖÐÏêϸµÄ˵Ã÷Á˹¹ÔìºÍʹÓöà·¸´ÓÃÆ÷µÄ·½·¨¡£ÕâÀï¾Í²»ÔÙÏêÊöÁË¡£
    ¡¡
    ÎÒÃÇÏÂÃæ·Ö±ðÌÖÂÛ¶à·I/OµÄÁ½ÖÖʵÏÖ·½·¨:

    1. ·Ç×èÈûͨÐÅ·½·¨

    ¶ÔÒ»¸öÎļþÃèÊö·ûÖ¸¶¨µÄÎļþ»òÉ豸, ÓÐÁ½ÖÖ¹¤×÷·½Ê½: ×èÈûÓë·Ç×èÈû¡£Ëùν×èÈû·½Ê½µÄÒâ˼ÊÇÖ¸, µ±ÊÔͼ¶Ô¸ÃÎļþÃèÊö·û½øÐжÁдʱ, Èç¹ûµ±Ê±Ã»Óж«Î÷¿É¶Á,»òÕßÔÝʱ²»¿Éд, ³ÌÐò¾Í½øÈëµÈ´ý״̬, Ö±µ½Óж«Î÷¿É¶Á»òÕß¿ÉдΪֹ¡£¶ø¶ÔÓÚ·Ç×èÈû״̬, Èç¹ûûÓж«Î÷¿É¶Á, »òÕß²»¿Éд, ¶Áдº¯ÊýÂíÉÏ·µ»Ø, ¶ø²»»áµÈ´ý¡£È±Ê¡Çé¿öÏÂ, ÎļþÃèÊö·û´¦ÓÚ×èÈû״̬¡£ÔÚʵÏÖÁÄÌìÊÒʱ, server ÐèÒªÂÖÁ÷²éѯÓë¸÷client ½¨Á¢µÄ socket, Ò»µ©¿É¶Á¾Í½«¸Ã socket ÖеÄ×Ö·û¶Á³öÀ´²¢ÏòËùÓÐÆäËûclient ·¢ËÍ¡£²¢ÇÒ, server »¹ÒªËæʱ²é¿´ÊÇ·ñÓÐÐ嵀 client ÊÔͼ½¨Á¢Á¬½Ó,ÕâÑù, Èç¹û server ÔÚÈκÎÒ»¸öµØ·½×èÈûÁË, ÆäËû client ·¢Ë͵ÄÄÚÈݾͻáÊܵ½Ó°Ïì,µÃ²»µ½·þÎñÆ÷µÄ¼°Ê±ÏìÓ¦¡£Ð client ÊÔͼ½¨Á¢Á¬½ÓÒ²»áÊܵ½Ó°Ïì¡£ËùÒÔÎÒÃÇÔÚÕâÀï²»ÄÜʹÓÃȱʡµÄ×èÈûµÄÎļþ¹¤×÷·½Ê½£¬¶øÐèÒª½«ÎļþµÄ¹¤×÷·½Ê½±ä³É·Ç×èÈû·½Ê½¡£ÔÚUNIXÏ£¬º¯Êýfcntl()¿ÉÒÔÓÃÀ´¸Ä±äÎļþI/O²Ù×÷µÄ¹¤×÷·½Ê½£¬º¯ÊýÃèÊöÈçÏ£º

    fcntl( sockfd, F_SETFL, O_NONBLOCK);
    // sockfd ÊÇÒª¸Ä±ä״̬µÄÎļþÃèÊö·û.
    // F_SETFL ±íÃ÷Òª¸Ä±äÎļþÃèÊö·ûµÄ״̬
    // O_NONBLOCK ±íʾ½«ÎļþÃèÊö·û±äΪ·Ç×èÈûµÄ.

    ΪÁ˽Úʡƪ·ùÎÒÃÇʹÓÃ×ÔÈ»ÓïÑÔÃèÊöÁÄÌìÊÒ server :

    while ( 1) {
    if ÓÐÐÂÁ¬½Ó then ½¨Á¢²¢¼Ç¼¸ÃÐÂÁ¬½Ó;
    for ( ËùÓеÄÓÐЧÁ¬½Ó)
    begin
    if ¸ÃÁ¬½ÓÖÐÓÐ×Ö·û¿É¶Á then
    begin
    ¶ÁÈë×Ö·û´®£»
    for ( ËùÓÐÆäËûµÄÓÐЧÁ¬½Ó)
    begin
    ½«¸Ã×Ö·û´®·¢Ë͸ø¸ÃÁ¬½Ó;
    end;
    end;
    end;
    end.

    ÓÉÓÚÅжÏÊÇ·ñÓÐÐÂÁ¬½Ó, ÊÇ·ñ¿É¶Á¶¼ÊÇ·Ç×èÈûµÄ, Òò´Ëÿ´ÎÅжÏ,²»¹ÜÓл¹ÊÇûÓÐ, ¶¼»áÂíÉÏ·µ»Ø. ÕâÑù,ÈκÎÒ»¸ö client Ïò server ·¢ËÍ×Ö·û»òÕßÊÔͼ½¨Á¢ÐÂÁ¬½Ó, ¶¼²»»á¶ÔÆäËû client µÄ»î¶¯Ôì³ÉÓ°Ïì¡£

    ¶Ô client ¶øÑÔ, ½¨Á¢Á¬½ÓÖ®ºó, Ö»ÐèÒª´¦ÀíÁ½¸öÎļþÃèÊö·û, Ò»¸öÊǽ¨Á¢ÁËÁ¬½ÓµÄ socket ÃèÊö·û, ÁíÒ»¸öÊDZê×¼ÊäÈë. ºÍ server Ò»Ñù, Èç¹ûʹÓÃ×èÈû·½Ê½µÄ»°, ºÜÈÝÒ×ÒòΪÆäÖÐÒ»¸öÔÝʱûÓÐÊäÈë¶øÓ°ÏìÁíÍâÒ»¸öµÄ¶ÁÈë.. Òò´Ë½«ËüÃǶ¼±ä³É·Ç×èÈûµÄ, È»ºóclient ½øÐÐÈç϶¯×÷:

    while ( ²»ÏëÍ˳ö)
    begin
    if ( Óë server µÄÁ¬½ÓÓÐ×Ö·û¿É¶Á)
    begin
    ´Ó¸ÃÁ¬½Ó¶ÁÈë, ²¢Êä³öµ½±ê×¼Êä³öÉÏÈ¥.
    End;
    if ( ±ê×¼ÊäÈë¿É¶Á)
    Begin
    ´Ó±ê×¼ÊäÈë¶ÁÈë, ²¢Êä³öµ½Óë server µÄÁ¬½ÓÖÐÈ¥.
    End;
    End.

    ÉÏÃæµÄ¶Áд·Ö±ðµ÷ÓÃÕâÑùÁ½¸öº¯Êý:

    read( userfd[i], line, MAX_LINE);
    // userfd[i] ÊÇÖ¸µÚ i ¸ö client Á¬½ÓµÄÎļþÃèÊö·û.
    // line ÊÇÖ¸¶Á³öµÄ×Ö·û´æ·ÅµÄλÖÃ.
    // MAX_LINE ÊÇÒ»´Î×î¶à¶Á³öµÄ×Ö·ûÊý.
    // ·µ»ØÖµÊÇʵ¼Ê¶Á³öµÄ×Ö·ûÊý.

    write( userfd[j], line, strlen( line));
    // userfd[j] ÊÇµÚ j ¸ö client µÄÎļþÃèÊö·û.
    // line ÊÇÒª·¢Ë͵Ä×Ö·û´®.
    // strlen( line) ÊÇÒª·¢Ë͵Ä×Ö·û´®³¤¶È.

    ·ÖÎöÉÏÃæµÄ³ÌÐò¿ÉÒÔÖªµÀ, ²»¹ÜÊÇ server »¹ÊÇ client, ËüÃǶ¼²»Í£µÄÂÖÁ÷²éѯ¸÷¸öÎļþÃèÊö·û, Ò»µ©¿É¶Á¾Í¶ÁÈë²¢½øÐд¦Àí. ÕâÑùµÄ³ÌÐò, ²»Í£µÄÔÚÖ´ÐÐ, Ö»ÒªÓÐCPU ×ÊÔ´, ¾Í²»»á·Å¹ý¡£Òò´Ë¶Ôϵͳ×ÊÔ´µÄÏûºÄ·Ç³£´ó¡£server »òÕß client µ¥¶ÀÖ´ÐÐʱ, CPU ×ÊÔ´µÄ 98% ×óÓÒ¶¼±»ÆäÕ¼Ó᣼«´óµÄÏûºÄÁËϵͳ×ÊÔ´¡£

    select ·½·¨
    Òò´Ë£¬ËäÈ»ÎÒÃDz»Ï£ÍûÔÚijһ¸öÓû§Ã»Óз´Ó¦Ê±×èÈûÆäËûµÄÓû§£¬µ«ÎÒÃÇÈ´Ó¦¸ÃÔÚûÓÐÈκÎÓû§Óз´Ó¦µÄÇé¿öÖ®ÏÂÍ£Ö¹³ÌÐòµÄÔËÐУ¬ÈóöÇÀÕ¼µÄϵͳ×ÊÔ´£¬½øÈë×èÈû״̬¡£ÓÐûÓÐÕâÖÖ·½·¨ÄØ£¿ÏÖÔÚµÄUNIXϵͳÖж¼ÌṩÁËselect·½·¨£¬¾ßÌåʵÏÖ·½Ê½ÈçÏ£º
    select ·½·¨ÖÐ, ËùÓÐÎļþÃèÊö·û¶¼ÊÇ×èÈûµÄ. ʹÓà select ÅжÏÒ»×éÎļþÃèÊö·ûÖÐÊÇ·ñÓÐÒ»¸ö¿É¶Á(д), Èç¹ûûÓоÍ×èÈû, Ö±µ½ÓÐÒ»¸öµÄʱºò¾Í±»»½ÐÑ. ÎÒÃÇÏÈ¿´±È½Ï¼òµ¥µÄ client µÄʵÏÖ:

    ÓÉÓÚ client Ö»ÐèÒª´¦ÀíÁ½¸öÎļþÃèÊö·û, Òò´Ë, ÐèÒªÅжÏÊÇ·ñÓпɶÁдµÄÎļþÃèÊö·ûÖ»ÐèÒª¼ÓÈëÁ½Ïî:

    FD_ZERO( sockset);
    // ½« sockset Çå¿Õ
    FD_SET( sockfd, sockset);
    // °Ñ sockfd ¼ÓÈëµ½ sockset ¼¯ºÏÖÐ
    FD_SET( 0, sockset);
    // °Ñ 0 (±ê×¼ÊäÈë) ¼ÓÈëµ½ sockset ¼¯ºÏÖÐ

    È»ºó client µÄ´¦ÀíÈçÏÂ:

    while ( ²»ÏëÍ˳ö) {
    select( sockfd+1, &sockset, NULL, NULL, NULL);
    // ´Ëʱ¸Ãº¯Êý½«×èÈûÖ±µ½±ê×¼ÊäÈë»òÕß sockfd ÖÐÓÐÒ»¸ö¿É¶ÁΪֹ
    // µÚÒ»¸ö²ÎÊýÊÇ 0 ºÍ sockfd ÖеÄ×î´óÖµ¼ÓÒ»
    // µÚ¶þ¸ö²ÎÊýÊÇ ¶Á¼¯, Ò²¾ÍÊÇ sockset
    // µÚÈý, Ëĸö²ÎÊýÊÇд¼¯ºÍÒì³£¼¯, ÔÚ±¾³ÌÐòÖж¼Îª¿Õ
    // µÚÎå¸ö²ÎÊýÊdz¬Ê±Ê±¼ä, ¼´ÔÚÖ¸¶¨Ê±¼äÄÚÈÔûÓпɶÁ, Ôò³ö´í
    // ²¢·µ»Ø. µ±Õâ¸ö²ÎÊýΪNULL ʱ, ³¬Ê±Ê±¼ä±»ÉèÖÃΪÎÞÏÞ³¤.
    // µ± select ÒòΪ¿É¶Á·µ»Øʱ, sockset Öаüº¬µÄÖ»ÊǿɶÁµÄ
    // ÄÇЩÎļþÃèÊö·û.
    if ( FD_ISSET( sockfd, &sockset)) {
    // FD_ISSET Õâ¸öºêÅÐ¶Ï sockfd ÊÇ·ñÊôÓڿɶÁµÄÎļþÃèÊö·û
    ´Ó sockfd ÖжÁÈë, Êä³öµ½±ê×¼Êä³öÉÏÈ¥.
    }

    if ( FD_ISSET( 0, &sockset)) {
    // FD_ISSET Õâ¸öºêÅÐ¶Ï sockfd ÊÇ·ñÊôÓڿɶÁµÄÎļþÃèÊö·û
    ´Ó±ê×¼ÊäÈë¶ÁÈë, Êä³öµ½ sockfd ÖÐÈ¥.
    }
    ÖØÐÂÉèÖà sockset. (¼´½« sockset Çå¿Õ, ²¢½« sockfd ºÍ 0 ¼ÓÈë)
    }

    ÏÂÃæ¿´ server µÄÇé¿ö:

    ÉèÖà sockset ÈçÏÂ:

    FD_ZERO( sockset);
    FD_SET( sockfd, sockset);
    for ( ËùÓÐÓÐЧÁ¬½Ó)
    FD_SET( userfd[i], sockset);
    }
    maxfd = ×î´óµÄÎļþÃèÊö·ûºÅ + 1;

    server ´¦ÀíÈçÏÂ:

    while ( 1) {
    select( maxfd, &sockset, NULL, NULL, NULL);
    if ( FD_ISSET( sockfd, &sockset)) {
    // ÓÐÐÂÁ¬½Ó
    ½¨Á¢ÐÂÁ¬½Ó, ²¢½«¸ÃÁ¬½ÓÃèÊö·û¼ÓÈëµ½ sockset ÖÐÈ¥ÁË.
    }
    for ( ËùÓÐÓÐЧÁ¬½Ó) {
    if ( FD_ISSET ( userfd[i], &sockset)) {
    // ¸ÃÁ¬½ÓÖÐÓÐ×Ö·û¿É¶Á
    ´Ó¸ÃÁ¬½ÓÖжÁÈë×Ö·û, ²¢·¢Ë͵½ÆäËûÓÐЧÁ¬½ÓÖÐÈ¥.
    }

    }
    ÖØÐÂÉèÖÃ sockset;
    }

    ÐÔÄܱȽÏ

    ÓÉÓÚ²ÉÓà select »úÖÆ, Òò´Ëµ±Ã»ÓÐ×Ö·û¿É¶Áʱ, ³ÌÐò´¦ÓÚ×èÈû״̬,×îС³Ì¶ÈµÄÕ¼ÓÃCPU ×ÊÔ´, ÔÚͬһ̨»úÆ÷ÉÏÖ´ÐÐÒ»¸ö server ºÍÈô¸É¸öclient ʱ, ϵͳ¸ºÔØÖ»ÓÐ 0.1 ×óÓÒ, ¶ø²ÉÓÃÔ­À´µÄ·Ç×èÈûͨÐÅ·½·¨, Ö»ÔËÐÐÒ»¸ö server, ϵͳ¸ºÔؾͿÉÒÔ´ïµ½ 1.5 ×óÓÒ. Òò´ËÎÒÃÇÍƼöʹÓà select.

    ²Î¿¼ÎÄÏ×£º

    [1] UNIX Network Programming Volume 1 W.Richard Stevens 1998 Prentice Hall
    [2] ¼ÆËã»úʵÓÃÍøÂç±à³Ì ÌÀÒã¼á 1993 ÈËÃñÓʵç³ö°æÉç
    [3] UNIX? SYSTEM V RELEASE 4 Programmer\s Guide:STREAMS AT&T 1990 Prentice Hall
    [4] UNIX? SYSTEM V RELEASE 4 Network Programmer\s Guide AT&T 1990 Prentice Hall

    ËùÓÐÔ´³ÌÐò¾ùµÇÔØÔÚeDOCÍøÕ¾ÉÏ£¬ÈçÓÐÐèÒª¿ÉÒÔÈ¥http://edoc.163.netÏÂÔØ

    ×÷Õß½éÉÜ£º

    ÐÕÃû£ºÀ×ÔÆ·É
    ±ÊÃû£ºeDOC¹¤×÷×é
    ÁªÏµµØÖ·£º °²»ÕÊ¡ºÏ·ÊÊÐËĺÅÐÅÏä2331 230027
    ·¢²¼ÈË:netbull À´×Ô:Linux¹«±¨