linuxselectsocket
『壹』 linux socket編程、server端有幾個socket綁定不同埠、想用select函數實
fd_set rdfds; /* 先申明一個 fd_set 集合來保存我們要檢測的 socket句柄 */
struct timeval tv; /* 申明一個時間變數來保存時間 */
int ret; /* 保存返回值 */
FD_ZERO(&rdfds); /* 用select函數之前先把集合清零 */
FD_SET(socket, &rdfds); /* 把要檢測的句柄socket加入到集合里 */
tv.tv_sec = 1;
tv.tv_usec = 500; /* 設置select等待的最大時間為1秒加500毫秒 */
ret = select(socket + 1, &rdfds, NULL, NULL, &tv); /* 檢測我們上面設置到集合rdfds里的句柄是否有可讀信息 */
if(ret < 0) perror("select");/* 這說明select函數出錯 */
else if(ret == 0) printf("超時\n"); /* 說明在我們設定的時間值1秒加500毫秒的時間內,socket的狀態沒有發生變化 */
else { /* 說明等待時間還未到1秒加500毫秒,socket的狀態發生了變化 */
printf("ret=%d\n", ret); /* ret這個返回值記錄了發生狀態變化的句柄的數目,由於我們只監視了socket這一個句柄,所以這里一定正大ret=1,如果同時有多個句柄舉陵豎發生變化返回的就是句柄的總和了 */
/* 這里我們就應該從socket這個句柄里讀取數據了,因為select函數已經告訴我們這個句柄里有數據可讀 */
if(FD_ISSET(socket, &rdfds)) { /* 先判斷一下socket這外被監視的句柄是否真的變成可讀的了 */
/* 讀取socket句汪賀柄里的數據 */
recv(...);
}
}
『貳』 Linux網路編程:select函數的用法和原理
在Linux網路編程中,select函數扮演著關鍵角色,它的主要功能是檢測一組socket中是否有事件就緒。具體來說,這些事件可以分為三類。
select()函數的用法如下:
參數說明:
其定義如下:
參數readfds,writefds,exceptfds的類型都是fd_set,這是一個結構體信息。
定義如下:
假設未定義__USE_XOPEN整理一年
將一個fd添加到fd_set這個集合中時需要使用FD_SET宏,其定義如下:
實現如下:
__FD_SET (fd, fdsetp)實現如下:
舉個例子,假設現在fd的值為43,那麼在數組下表為0的元素中第43個bit被置為1。
在Linux上,向fd_set集合中添加新的fd時,採用點陣圖法確定位置;而在Windows中,添加fd至fd_set的實現規則依次從數組第0個位置開始向後遞增。
也就是說,FD_SET宏本質上是在一個有1024個連續bit的數組的第fd位置置1。
同理,FD_CLR刪除一個fd的原理,也就是將數組的第fd位置置為0。
實例:
使用nc -v 127.0.0.1 3000來模擬客戶端,打開三個終端。
關於以上代碼,需要注意以下幾點:
windows上的socket函數
在Windows上,select函數結束後,不會修改timeval函數。