Linux C recv函式阻塞問題

2021-10-10 07:38:06 字數 1687 閱讀 8410

有個linux專案用到tcp/ip通訊,但是recv()函式老是阻塞,沒有返回;setsockopt()也設定了超時時間,同時在執行recv()之前也增加了select()檢視套接字的狀態,如果狀態異常異常是不會執行recv()函式的

1、recv()是linux的系統函式,肯定不會卡死,除非linux核心故障,基本可以排除;

2、客戶端向伺服器端傳送資料,伺服器端沒有接收,導致緩衝區滿,客戶端無法接收資料,因此客戶端阻塞?等等,我不是加了超時嗎?怎麼還會阻塞?

3、讀寫超時設定有問題?還真是,其他函式都做了返回值判斷,唯獨讀寫超時沒有判斷返回值,因此沒及時發現問題;讀寫超時呼叫的函式時setsockopt(),返回-1,執行失敗了,所以recv()一直阻塞

setsockopt() 函式原型如下:

int

setsockopt

(int sockfd,

int level,

int optname,

const

void

*optval, socklen_t optlen)

;

sockfd:標識乙個套介面的描述字。

level:選項定義的層次;支援sol_socket、ipproto_tcp、ipproto_ip和ipproto_ipv6。

optname:需設定的選項。

optval:指標,指向存放選項待設定的新值的緩衝區。

optlen:optval緩衝區長度。

以下是我的使用方式:

int ntimeout=

1000

;//1秒

// 傳送超時

setsockopt

(socket,sol_s0cket, so_sndtimeo,

(char*)

&nnettimeout,

sizeof

(int))

;// 接收超時

setsockopt

(socket,sol_s0cket, so_rcvtimeo,

(char*)

&nnettimeout,

sizeof

(int))

;

上面是 windows 的用法,對於設定 so_sndtimeo 和 so_rcvtimeo,windows環境下只能傳 dword;linux 環境下, 只能傳結構體 struct timeval,傳 int 會失敗,須如下使用:

struct timeval timeout =

;// 分別是秒和毫秒

// 傳送超時

setsockopt

(socket,sol_socket,so_sndtimeo,(

char*)

&timeout,

sizeof

(struct timeval));

// 接收超時

setsockopt

(socket,sol_socket,so_rcvtimeo,(

char*)

&timeout,

sizeof

(struct timeval)

);

send函式阻塞

tcp協議本身是可靠的,並不等於應用程式用tcp傳送資料就一定是可靠的.不管是否阻塞,send傳送的大小,並不代表對端recv到多少的資料.在阻塞模式 下,send函式的過程是將應用程式請求傳送的資料拷貝到傳送快取中傳送就返回.但由於傳送快取的存在,表現為 如果傳送快取大小比請求傳送的大小要大,那麼...

Java基礎361問8問 阻塞佇列的原理

我們知道執行緒池是靠阻塞佇列實現的,那麼這個阻塞佇列是具體如何實現阻塞的呢?說到阻塞我們能想到執行緒的sleep和object類的wait方法,seep是讓執行緒睡眠若干秒再去執行,而wait是讓執行緒休眠如果不通知執行緒恢復,那麼執行緒將一直休眠下去不進行任何操作。所以我們想到的乙個辦法是通過wa...

巧用loopback模式,定位CAN阻塞問題

最近做的乙個can通訊專案,軟體在開發板上執行的時候跑的沒有一點問題,在專案的pcb上跑的時候can傳送總是阻塞在檢查can郵箱是否空閒裡無法跳出,can傳送函式如下 brief param argument retval uint8 t can txmessage can handletypede...