socket程式設計之select

2021-09-26 15:50:40 字數 2651 閱讀 7478

linux程式設計之select:

select作用是:在一段指定的時間內,監聽使用者感興趣的檔案描述符上可讀、可寫和異常等事件。

1、socket阻塞模式

通常在socket程式設計中,我們習慣於寫connect、accept、recv、recvfrom這樣的阻塞程式。如果事件不發生,程式就一直阻塞在那裡,無法返回。

2、socket非阻塞模式:select

用select就可以完成非阻塞,程序或執行緒執行到此函式時,不必非要等待事件的發生,執行到這裡之後,會根據select返回結果來反映執**況。如果事件發生,則根據發生時邏輯執行,如果沒發生,會繼續執行。它主要時監視我們需要監視的檔案描述符的變化情況——讀寫或是異常。

引數一:被監聽的檔案描述符的總數,它比所有檔案描述符集合中的檔案描述符的最大值大1,因為檔案描述符是從0開始計數的。

引數二:可讀檔案描述符集合

引數三:可寫檔案描述符集合

引數四:異常事件檔案描述符集合

引數五:用於設定超時時間。null表示無限等待,類似於阻塞。

返回值:0:超時;-1:失敗;成功返回大於0的整數,這個整數就是就緒描述符的數目。

#include #include #include #include int select(int maxfdp,fd_set *readset,fd_set *writeset,fd_set *exceptset,struct timeval *timeout);
fd_set可以理解為乙個集合,這個集合中存放了需要監控的檔案描述符。可以通過fd_zero,fd_set,fd_clr,fd_isset來進行操作。

struct timeval結構體:

struct timeval

;

操作fd_set的幾個巨集:

#include int fd_zero(int fd, fd_set *fdset); //乙個 fd_set型別變數的所有位都設為 0

int fd_clr(int fd, fd_set *fdset); //清除某個位時可以使用

int fd_set(int fd, fd_set *fd_set); //設定變數的某個位置位

int fd_isset(int fd, fd_set *fdset); //測試某個位是否被置位

使用範例:

fd_set rset;

int fd;

fd_zero(&rset);

fd_set(fd, &rset);

然後使用select函式:

select(fd+1, &rset, null, null, null);
select返回後,用fd_isset來測試是否置位:

if(fd_isset(fd, &rset))

原理解析:

服務端將需要進行io操作的socket新增到select中,然後等待select系統呼叫返回。當資料到達時,socket被啟用,select函式返回。服務端進行資料讀取。

可以看到,使用select函式進行io請求和同步阻塞模型沒有太大的區別,甚至還多了新增監視socket,以及呼叫select函式的額外操作。降低了效率。但使用select後,服務端可以在乙個執行緒內同時處理多個socket請求。服務端註冊好socket之後,可以通過select讀取被啟用的socket,即可達到在同乙個執行緒內同時處理多個io請求的目的。如果是在同步阻塞執行緒中,必須通過多執行緒來實現。

server.c

#include #include #include #include #include #include #include #include #define linten_queue 5

#define port 8888

#define maxlen 1024

int socket_bind_listen()

void socket_select(int server_sockfd)

else if (result == 0)

/*掃瞄所有的檔案描述符*/

for (fd = 0; fd < fd_setsize; fd++)

/*客戶端socket中有資料請求時*/

else

/*處理客戶資料請求*/

else

} }

} }

}int main()

client.c

#include #include #include #include #include #include #include #include #include int main() 

char buf[1024] = "hello";

send(client_sockfd, buf, strlen(buf), 0);

close(client_sockfd);

return 0;

}

參考:

Socket程式設計之Select

select在socket程式設計中還是比較重要的,可是對於初學socket的人來說都不太愛用select寫程式,他們只是習慣寫諸如connect accept recv或recvfrom這樣的阻塞程式 所謂阻塞方式block,顧名思義,就是程序或是執行緒執行到這些函式時必須等待某個事件的發生,如果...

C語言 Socket程式設計之Select函式

select在socket程式設計中還是比較重要的,可是對於初學socket的人來說都不太愛用select寫程式,他們只是習慣寫諸如connect accept recv或recvfrom這樣的阻塞程式 所謂阻塞方式block,顧名思義,就是程序或是執行緒執行到這些函式時必須等待某個事件的發生,如果...

網路程式設計之Socket程式設計

對 tcp ip udp socket 程式設計這些詞你不會很陌生吧?隨著網路技術的發展,這些詞充斥著我們的耳朵。那麼我想問 1.什麼是tcp ip udp?2.socket在 呢?3.socket是什麼呢?4.你會使用它們嗎?什麼是tcp ip udp?tcp ip transmission co...