connect 函式阻塞問題

2021-07-16 08:44:51 字數 1791 閱讀 1915

方法一:採用select

在學習嵌入式linux網路程式設計中,很多同學都發現了乙個問題,那就是呼叫connect函式時,如果服務端關閉,客戶 端呼叫connect()函式時,發現阻塞在那裡,而且利用ctrl+c訊號去停止客戶端程式時,需要等待乙個較為長的時間才能響應了,這個時間如果大家 細心會發現,每次都是75秒的時間。那麼有沒有什麼比較好的辦法,可以以使用者能接受的乙個時間響應來停止掉乙個正在connect連線的客戶端那?比如我 們在做乙個網路控制台的程式,使用者需要隨時可以停止掉任何乙個網路服務連線,那麼對於這樣乙個需要等待75秒時間才能反饋出服務狀態的程式,使用者是無法接 受的。

對於如何解決這個問題,我們可以分析下,要想完成使用者在乙個能接受的時間裡迅速反饋出服務 端已經關閉的狀態,那麼我們的程式應該做到在乙個規定的時間片內,可以捕獲到使用者發出的控制狀態,然後處理使用者的需求。那麼要做到可以在規定的時間片內捕 獲使用者的控制狀態,就必須禁止讓我們的connect()函式阻塞75秒的情況發生,也就是說,要讓connect()函式變為非阻塞狀態才行。

好了,現在解決問題的關鍵就是如何把connect變為非阻塞狀態了,我們知道,socket程式設計的操作物件是socket,而socket他又屬於系統描述符型別,那麼對於系統描述符,我們是怎麼操作他變為非阻塞的那?是利用fcntl()函式或者ioctl()函式。

想到這裡,好像問題應該已經解決了,但是我們除錯發現,在服務端出現錯誤的時候,connect確實馬上返回,但是,如果服務端正確那,connect還是馬上返回,這樣,我們無法判斷connect函式是否成功了,那這個問題又該如何解決呢?

我們是否想到了乙個select函式那,他具備監聽檔案描述符的功能,如果我們把之前的socket讓select監聽他是否可寫,是不是問題也就解決了。

好了,那麼我們總結下整個思路:

1.建立socket

2.將該socket設定為非阻塞模式

3.呼叫connect()

4.使用select()檢查該socket描述符是否可寫

5.根據select()返回的結果判斷connect()結果

6.將socket設定為阻塞模式(如果你的程式不需要用阻塞模式,這步就省了,不過一般情況都是用阻塞模式,這樣容易管理)

那麼根據上面的6個步驟,我們寫乙個簡單的模組程式來除錯看下:

else ret = false;

}else ret = true;

ul = 0;

ioctl(sockfd, fionbio, &ul); //設定為阻塞模式

//下面還可以進行發包收包操作

……………

}方法二:定義訊號處理函式

sigset(sigalrm, u_alarm_handler)

;alarm(2)

;code = connect(socket_fd,

(struct sockaddr*

)&socket_st, sizeof(struct sockaddr_in));

alarm(0)

;sigrelse(sigalrm);

首先定義乙個中斷訊號處理函式u_alarm_handler,用於超時後的報警處理,然後定義乙個2秒的定時器,執行connect,當系統 connect成功,則系統正常執行下去;如果connect不成功阻塞在這裡,則超過定義的2秒後,系統會產生乙個訊號,觸發執行 u_alarm_handler函式, 當執行完u_alarm_handler後,程式將繼續從connect的下面一行執行下去。

其中,處理函式可以如下定義,也可以加入更多的錯誤處理。

void u_alarm_handler()

套接字中connect阻塞與非阻塞問題

1 intpascal far connect socket s,conststructsockaddr far name,intnamelen 1 如果伺服器端程式已經執行,客戶端執行connect 函式,正常沒問題,2 如果服務端程式沒有執行的時候,客戶端執行connect 函式,會在此函式停留...

關於connect前設定非阻塞的問題

此處僅設定socket的狀態為ss connecting表示連線狀態正在處理 不同之處在於非阻塞情況下,返回值設定為 einprogress表示操作正在處理 而阻塞式情況則在獲得ack包後將返回值置為 ealready.err einprogress break timeo sock sndtime...

非阻塞connect的實現

需要非阻塞connec的幾種情況 1.三路握手需要時間,這個要視具體的網路情況而定。當然也有可能失敗。在三路握手的時候我們並不需要在原地等待三路握手的完成,可以用這些時間來完成其它事情,然後當這些事情完成後,再去檢測連線是否建立 也就是三路握手是否完成 2.可以用這種技術來同時建立多個連線。web瀏...