socket程式設計 select方法使用

2021-07-12 06:02:52 字數 1980 閱讀 4895

0.背景

最近要寫乙個rpc庫,即在客戶端向服務端傳送請求,伺服器計算並返回結果,要求實現服務端能同時接收多個客戶端請求但是不能使用執行緒庫,根據提示我知道了可以使用select函式來完成非阻塞方式工作的程式,於是我就開始了select方法的學習。

1.概念

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

可是使用select就可以完成非阻塞(所謂非阻塞方式non-block,就是程序或執行緒執行此函式時不必非要等待事件的發生,一旦執行肯定返回,以返回值的不同來反映函式的執**況,如果事件發生則與阻塞方式相同,若事件沒有發生則返回乙個**來告知事件未發生,而程序或執行緒繼續執行,所以效率較高)方式工作的程式,它能夠監視我們需要監視的檔案描述符的變化情況——讀寫或是異常。

2.程式設計

我第一步是準備先熟悉select的簡單使用,所以我在我的centos伺服器上先編輯好如下**:

#include#include#include#include#include#include#include#include#include#includeint main()

; myaddr.sin_family=af_inet;

myaddr.sin_addr.s_addr=htonl(inaddr_any);

myaddr.sin_port=htons(4600);

char buf[16];

//socket

server_fd=socket(af_inet,sock_stream,0);

if(server_fd==-1)

//bind

if(bind(server_fd,(struct sockaddr *)&myaddr,sizeof(myaddr))==-1)

//listen

if(listen(server_fd,20)==-1)

printf("listening~\n");

client_fd=accept(server_fd,(struct sockaddr *)&clientaddr,&clientaddr_len);

while(1)}}

close(server_fd);

}

客戶端程式比較簡單,所以我就不上**了,這裡重點想討論一下我在完成這個程式中遇到的問題。

3.問題

在完成這個程式之前我看過許多解釋select方法的部落格,有windows環境下的,有linux環境下的,但是都沒有能正確執行的**,我想大家也是為了捍衛自己的版權,所以貼的都是偽碼,不過也多虧了大家的共享精神我最終才能解決這些小問題。

1)在使用fd_set這個結構體宣告變數的時候,我本來寫的是:

struct fd_set fds

這也是很多博主的寫法,但是我這樣寫在centos下用gcc編譯會報錯,搜尋那個錯誤提示也沒有找到相關聯的答案,所以我就去掉了前面的struct關鍵字,然後一套編譯下來,居然連乙個警告都沒有就通過了。

2)原本我根據別人的**模仿著寫的時候在監聽之後並沒有寫accept這個過程,因為別人都沒寫

3)我在網上又搜尋了一陣子之後,意識到了上面那個問題,所以同樣依葫蘆畫瓢將accept方法寫在了死迴圈裡面,但是在fd_isset方法判斷socket描述符是否可讀寫時,我又犯了乙個錯,因為我判斷的是server_fd,這個描述符無論有沒有連線請求狀態都是不變的,所以在除錯程式的時候同樣無法連通。

最後意識到上述問題之後,我想到,既然select要檢測的是變幻的socket描述符,那結合之前accept方法返回的客戶端描述符,怎麼做方法就很明顯了,即用select方法來檢測accept返回的檔案描述符,也就是有客戶端連線請求就可以在select的switch語句中進行傳送和接收了,如程式所示。

Select在Socket程式設計中的使用方法

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

Socket程式設計之Select

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

socket程式設計之select

linux程式設計之select select作用是 在一段指定的時間內,監聽使用者感興趣的檔案描述符上可讀 可寫和異常等事件。1 socket阻塞模式 通常在socket程式設計中,我們習慣於寫connect accept recv recvfrom這樣的阻塞程式。如果事件不發生,程式就一直阻塞在...