linux 下socket 伺服器和客戶端非同步通訊

2021-08-02 23:03:56 字數 2334 閱讀 5026

我們知道用socket進行通訊時,傳送資料和接收資料所使用的recv/send函式會阻塞程序,只有收到或傳送資料後才能返回值,導致是socket通訊只能實現伺服器和客戶端交替收發資料,而使用select可以很好地解決這個問題。

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

select函式的原型:int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval*timeout); 關於select函式的用法和作用,大家看看這個帖子

這個帖子已經講的很詳細了,大家可以看一看,關於select如何解決socket的非同步通訊問題,個人的理解:select的作用在於,以輪詢的方式 同時對「自己有無傳送資料」 「對方有無傳送資料」同時進行監控。而每次檢測的時間限制為 struct timeval * timeout 中自己設定的時間,在檢測的這段時間內,程序/執行緒會阻塞。這樣就可以不斷地交替對「 是否傳送了資料」和「是否接收到資料」進行不斷交替檢測,這樣,程序就不會被recv或是send阻塞,從而實現了非同步通訊。

**如下:

伺服器 server.c

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define port 7000

#define queue 20

int main()

if(listen(listenfd, queue) == -1)

struct sockaddr_in client_addr;

socklen_t length = sizeof(client_addr);

int fd = accept(listenfd, (struct sockaddr*)&client_addr, &length);

if( fd < 0 )

printf("you got connected from:%s\n",inet_ntoa(client_addr.sin_addr));

while(1) else

if(retval == 0)else

/*使用者輸入資訊了,開始處理資訊並傳送*/

if(fd_isset(0, &rfds))}}

close(fd);

close(listenfd);

return

0;}

客戶端 client.c

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define port 7000

#define buffer_size 1024

int main()

while(1)else

if(retval == 0)else

/*使用者輸入資訊了,開始處理資訊並傳送*/

if(fd_isset(0, &rfds))}}

close(fd);

return

0;}

個人理解:以客戶端為例,在上述**中,若fd_isset(fd,&rfds)不為0,則表示接收到了資料,這是因為socket的資料傳輸是通過讀寫檔案描述符來實現的,所以伺服器傳送資料時,select可以檢測到檔案描述符已被讀寫,於是接收資料。而select中0 1 2分別表示標準輸入,標準輸出,標準錯誤。符若fd_isset(0,&rfds)不為0,則表示使用者已經輸入了資料,於是傳送資料。

linux下socket程式設計之時間伺服器

為網路上的使用者提供時間服務,即為網路使用者返回伺服器的當前時間 記錄發出請求的網路使用者的ip位址 儲存到檔案中 編寫時間服務客戶端timeclient,該客戶端能夠向伺服器傳送時間服務請求,並把獲得的時間返回給使用者。開發環境 fedora13,vim,gcc timeserver.c檔案。in...

Linux下Socket伺服器與客戶端程式設計

對於socket程式設計零基礎,同時也沒有在linux下程式設計的經驗,分享給和我一樣的朋友。伺服器接收客戶端多次傳過來訊息,同時返回給客戶端進行迴圈處理。伺服器得起乙個執行緒,處理客戶端傳過來的訊息,否則伺服器與客戶端只能通訊一次。客戶端 code include include include ...

伺服器模型 socket

伺服器模型 一 迴圈伺服器 迴圈伺服器在同一時刻只可以相應乙個客戶端請求 二 併發伺服器 併發伺服器在同一時刻可以相應多個客戶端的請求.迴圈伺服器 1.udp伺服器 udp迴圈伺服器的實現非常簡單 udp伺服器每次從套接字上讀取乙個客戶端的請求,處理,然後將結果返回給客戶機.可以用下面的演算法來實現...