注:select 原理圖,摘自ibm iseries 資訊中心。
返回值
返回對應位仍然為1的fd的總數。引數 1.2.1 清空描述符集合
fd_zero(fd_set *)
1.2.2 向描述符集合新增指定描述符fd_set(int, fd_set *)
1.2.3 從描述符集合刪除指定描述符fd_clr(int, fd_set *)
1.2.4 檢測指定描述符是否在描述符集合中fd_isset(int, fd_set *)
1.2.5 描述符最大數量#define fd_setsize 1024
可讀描述符集合中可讀的描述符,為1,其他為0;可寫也類似。異常描述符集合中有異常等待處理的描述符的值為1,其他為0。
程式各部分的解釋在注釋中。
#include #include #include #include #include #include #include #include #include #define true 1
#define false 0
int main(int argc, char *argv)
// set socket options
rc = setsockopt(listen_sd, sol_socket, so_reuseaddr, (char *) &on, sizeof(on));
if (rc < 0)
// set io control
rc = ioctl(listen_sd, fionbio, (char *) &on);
if (rc < 0)
// bind
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = af_inet;
server_addr.sin_addr.s_addr = htonl(inaddr_any);
server_addr.sin_port = htons(atoi(argv[1]));
rc = bind(listen_sd, (struct sockaddr *) &server_addr, sizeof(server_addr));
if (rc < 0)
// listen
rc = listen(listen_sd, 32);
if (rc < 0)
// intialize sd set
fd_zero(&master_set);
max_sd = listen_sd;
fd_set(listen_sd, &master_set);
timeout.tv_sec = 3 * 60;
timeout.tv_usec = 0;
// start
doif (rc == 0)
desc_ready = rc; // number of sds ready in working_set
// check each sd in working_set
for (i = 0; i <= max_sd && desc_ready > 0; ++i)
break;
}// insert new_sd into master_set
printf(" new incoming connection - %d\n", new_sd);
fd_set(new_sd, &master_set);
if (new_sd > max_sd)
}while (new_sd != -1);
}// this is not the listening sd
else
break;
}// the connection has been closed by the client
if (rc == 0)
/* receiving data succeeded and echo it back
the to client */
len = rc;
printf(" %d bytes received\n", len);
rc = send(i, buffer, len, 0);
if (rc < 0)
}while (true);
// if unknown failure occured
if (close_conn)
} // end of if (i == max_sd)
} // end of if (close_conn)}}
}}
while (end_server == false);
/* close each sd in master_set */
for (i = 0; i < max_sd; ++i)
}return 0;
}
select io 多路復用
select主要用於檢測多個fd狀態,可檢測fd大小收核心編譯巨集 fd setsize限制,預設為1024。當開啟的fd較多時,select的效率會降低。可修改下面簡單伺服器模型為僅接受連線,當fd數量超過20000時,select返回明顯變慢。void testselectsocket else...
select I O多路復用
使用select函式的套接字 如果你想保持現有連線的同時,偵聽新的連線,怎麼辦呢?普通的做法 使用recv,accept是做不到的 當使用accetp等待新的連線時,程式是阻塞的,也就沒辦法再同原有連線保持通訊。另一種做法是,使用非阻塞方式,但這會浪費了寶貴的cpu時間 你的不停的輪詢輪詢 有沒有更...
select I O復用實現簡單web伺服器
要想實現乙個簡單的web伺服器模型,一般有以下幾種方法 1.多程序 主程序監聽,有新的連線就fork乙個子程序建立連線 2.多執行緒 主線程監聽,有新的連線就新建乙個子執行緒建立連線 3.使用系統函式select去監聽,當有檔案描述符就緒對其進行處理 4.使用系統函式poll去監聽,當有檔案描述符就...