導航:首頁 > 編程系統 > linuxrecv函數

linuxrecv函數

發布時間:2023-06-14 09:33:17

A. linux socket阻塞recv怎麼返回

recv是socket編程中最常用的函數之一,在阻塞狀態的recv有時候會返回不同的值,而對於錯誤值也有相應的錯誤碼,分別對應不同的狀態,下面是我針對常見的幾種網路狀態的簡單總結。
首先阻塞接收的recv有時候會返回0,這僅在對端已經關閉TCP連接時才會發生。
而當拔掉設備網線的時候,recv並不會發生變化,仍然阻塞,如果在這個拔網線階段,socket被關掉了,後果可能就是recv永久的阻塞了。
所以一般對於阻塞的socket都會用setsockopt來設置recv超時。
當超時時間到達後,recv會返回錯誤,也就是-1,而此時的錯誤碼是EAGAIN或者EWOULDBLOCK,POSIX.1-2001上允許兩個任意一個出現都行,所以建議在判斷錯誤碼上兩個都寫上。
如果socket是被對方用linger為0的形式關掉,也就是直接發RST的方式關閉的時候,recv也會返回錯誤,錯誤碼是ENOENT
還有一種經常在代碼中常見的錯誤碼,那就是EINTER,意思是系統在接收的時候因為收到其他中斷信號而被迫返回,不算socket故障,應該繼續接收。但是這種情況非常難再現,我嘗試過一邊一直在不停的發信號,一邊用recv接收數據,也沒有出現過。這種異常錯誤我附近只有一個朋友在用write的時候見到過一次,但是總是會有概率出現的,所以作為完善的程序必須對此錯誤進行特殊處理。
一般設置超時的阻塞recv常用的方法都如下:
while(1)
{
cnt = (int)recv(m_socket, pBuf,RECVSIZE, 0);
if( cnt >0 )
{
//正常處理數據
}
else
{
if((cnt<0) &&(errno == EAGAIN||errno == EWOULDBLOCK||errno == EINTR)) //這幾種錯誤碼,認為連接是正常的,繼續接收
{
continue;//繼續接收數據
}
break;//跳出接收循環
}
}
阻塞與非阻塞recv返回值沒有區分,都是 <0 出錯 =0 連接關閉 >0 接收到數據大小。

Linux環境下,須如下定義:struct timeval timeout = {3,0};
//設置發送超時
setsockopt(socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(struct timeval));
//設置接收超時
setsockopt(socket,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval));

B. recv是阻塞還是非阻塞的

網路編程函數如recv是阻塞(同步)還是非阻塞(非同步)取決於在調用recv函數前創建的套接字socket是阻塞還是非阻塞。socket默認創建時設定為阻塞模式;若要將socket設定為非阻塞模式,可以在socket創建時設定為非阻塞模式,那麼函數recv就是非阻塞的。
可以通過一下幾種方法設定socket為非阻塞:
1.linux平台可以在利用socket()函數創建socket時指定socket是非同步(非阻塞)的:
int socket(int domain, int type, int protocol);
在參數type中設置SOCK_NONBLOCK標志即可,例如:
int s = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
2.windows和linux平台accept()函數返回的socekt也是阻塞的,linux另外提供了一個accept4()函數,可以直接將socket設置為非阻塞模式:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
只要將accept4()最後一個參數flags設置成SOCK_NONBLOCK即可。

3.除了在創建socket時,將socket設置為非阻塞模式,還可以通過以下函數來設置:

linux平台可以調用fcntl()或ioctl()函數,例如:
fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK);
ioctl(sockfd, FIONBIO, 1); //1:非阻塞 0:阻塞
windows平台可調用ioctlsocket函數:

int ioctlsocket(
_In_ SOCKET s,
_In_ long cmd,
_Inout_ u_long *argp
);
將cmd參數設置為FIONBIO,*argp=0即設置成阻塞模式,而*argp非0即可設置成非阻塞模式。但windows平台一個地方需要注意,如果對一個socket調用了WSAAsyncSelect()或WSAEventSelect()函數後,你再調用ioctlsocket()函數將該socket設置為阻塞模式,則會失敗,必須先調用WSAAsyncSelect()設置lEvent參數為0或調用WSAEventSelect()設置lNetworkEvents參數為0來分別禁用WSAAsyncSelect()或WSAEventSelect(),再次調用ioctlsocket()將該socket設置成阻塞模式才會成功。因為調用WSAAsyncSelect()或WSAEventSelect()函數會自動將socket設置成非阻塞模式。

C. Linux中C語言的一個函數的源代碼:socket 編程中的 recv() 函數。

你好
recv函數只是在用戶空間定義的。內核空間有與之對應的函數,也就回是說,執行答recv函數就會調用到內核中與它對應的函數,實際起作用的就是內核里的這個函數。
至於內核里調用的是那個函數,你不需要是找,那樣會把你看暈的,內核里的調用關系復雜的很,除非對內核非常了解的,才會找到到底是怎麼調用的,他也是只是找到怎麼調用的,至於為什麼這樣調用是極少人知道的。得問linux的開發者。因為內核的代碼量是太多了。有人花了三年時間才看完內核代碼。

souce insight只能查找內核里有的東西,屬於內核的。recv()函數是不屬於內核的,所以用這個是查找不到的

希望可以幫到你,望選為滿意答案

D. 簡述linux下,從socket寫入和讀取的函數,read/write和send/recv函數的含義並解釋其介面意義簡答題

Ssize_t write(int fd,const void *buf,size_t nbytes);
write的返回值大於0,表示寫了部分數據或者是全部的數據,這樣用一個while循環不斷的寫入數據,但是循環過程中的buf參數和nbytes參數是我們自己來更新的,返回值小於0,此時出錯了,需要根據錯誤類型進行相應的處理
Ssize_t read(int fd,void *buf,size_t nbyte)
Read函數是負責從fd中讀取內容,當讀取成功時,read返回實際讀取到的位元組數,如果返回值是0,表示已經讀取到文件的結束了,小於0表示是讀取錯誤。
Recv函數和send函數
Recv函數和read函數提供了read和write函數一樣的功能,不同的是他們提供了四個參數。
Int
recv(int fd,void *buf,int len,int flags)
Int
send(int fd,void *buf,int len,int flags)
前面的三個參數和read、write函數是一樣的。第四個參數可以是0或者是一下組合:
MSG_DONTROUTE:不查找表
是send函數使用的標志,這個標志告訴IP,目的主機在本地網路上,沒有必要查找表,這個標志一般用在網路診斷和路由程序裡面。
MSG_OOB:接受或者發生帶外數據
表示可以接收和發送帶外數據。
MSG_PEEK:查看數據,並不從系統緩沖區移走數據
是recv函數使用的標志,表示只是從系統緩沖區中讀取內容,而不清楚系統緩沖區的內容。這樣在下次讀取的時候,依然是一樣的內容,一般在有過個進程讀寫數據的時候使用這個標志。
MSG_WAITALL:等待所有數據
是recv函數的使用標志,表示等到所有的信息到達時才返回,使用這個標志的時候,recv返回一直阻塞,直到指定的條件滿足時,或者是發生了錯誤。

E. linux中read,write和recv,send的區別

Linux的recv、send函數和read、write函數都可以用於套接字編程。
區別:
1、recv、send只用於套接字通信;
2、read、write是底層系統調用,只要是文件操作就都可以用, 比如套接字操作,套接字描述符屬於是文件描述符的一種,套接字本身在Linux上就叫做套接字文件。
所以read、write函數不光可以用於套接字編程,也可以用於讀取其他各種文件,比如用於文件編程讀寫普通文件。

F. recv函數返回什麼值

recv函數返回其實際的位元組數,如果recv在時出錯,那麼它返回SOCKET_ERROR。如果recv函數在等待協議接收數據時網路中斷了,那麼它返回0。

擴展閱讀,linux recv函數詳解:

1 #include <sys/socket.h>
2 ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags);
recv 的前3個參數等同於read函數。

flags參數值為0或:

flags
說明
recv
send

MSG_DONTWAIT
僅本操作非阻塞

MSG_OOB 發送或接收帶外數據

MSG_PEEK
窺看外來消息

MSG_WAITALL
等待所有數據

recv函數解析:

sockfd: 接收端套接字描述符

buff: 用來存放recv函數接收到的數據的緩沖區

nbytes: 指明buff的長度

flags: 一般置為0

1) recv先等待s的發送緩沖區的數據被協議傳送完畢,如果協議在傳送sock的發送緩沖區中的數據時出現網路錯誤,那麼recv函數返回SOCKET_ERROR

2)
如果套接字sockfd的發送緩沖區中沒有數據或者數據被協議成功發送完畢後,recv先檢查套接字sockfd的接收緩沖區,如果sockfd的接收緩
沖區中沒有數據或者協議正在接收數據,那麼recv就一起等待,直到把數據接收完畢。當協議把數據接收完畢,recv函數就把s的接收緩沖區中的數據
到buff中(注意協議接收到的數據可能大於buff的長度,所以在這種情況下要調用幾次recv函數才能把sockfd的接收緩沖區中的數據
完。recv函數僅僅是數據,真正的接收數據是協議來完成的)

3) recv函數返回其實際的位元組數,如果recv在時出錯,那麼它返回SOCKET_ERROR。如果recv函數在等待協議接收數據時網路中斷了,那麼它返回0。

4) 在unix系統下,如果recv函數在等待協議接收數據時網路斷開了,那麼調用 recv的進程會接收到一個SIGPIPE信號,進程對該信號的默認處理是進程終止。

G. linux中的socket編程的問題,recv函數收到的全是0

send後,操作系統會決定是不是馬山發包還是繼續等待看看還有別的send,然後把他們一起打成一個包來發送。所以你recv是不知道要接收幾個包的。

H. linux中read,write和recv,send的區別

Linux的recv、send函數和read、write函數都可以用於套接字編程。不同的是recv、send只用於套接字通信;而read、write是底層系統調用,只要是文件操作就都可以用, 比如套接字操作,套接字描述符屬於是文件描述符的一種,套接字本身在Linux上就叫做套接字文件。所以read、write函數不光可以用於套接字編程,也可以用於讀取其他各種文件,比如用於文件編程讀寫普通文件。這就是它們之間的區別

I. linux的socket編程中send recv函數是接收鍵盤的數據後發送嗎

1.
因為問題比較簡單,暫且可以認為send/recv

read/write
是一樣的.
2.
網路通信默認是阻塞的(不符合你的要求么?)。
你想要不阻塞的話,使用fcntl
設置為
非阻塞模式
即可。
3.
select
想用可以用,看你的客戶端有多少了,不用也無妨。

J. linux 下調用recv函數,死循環在recv函數裡面,什麼原因

建議你用strace看那幾個線程確切是卡在哪裡

而且你描述的是,死循環。 recv函數怎麼會死循環?

還有,當你的系統壓力變大的時候, 會出現epoll提示某socket可用,但是等你去讀的時候該socket已經被關閉的情況,你看看這種情況會不會對你的程序造成影響。
----------------------------
man recv
RETURN VALUE
These calls return the number of bytes received, or -1 if an error occurred. The return value will be 0 when the peer has performed an
orderly shutdown.

你可以看到,當對端關閉socket的時候recv返回值是0。 那麼作為你的程序,你又沒有判斷這種情況呢? 你默認的如果是使用EPOLLET模式, 你肯定不停的讀socket直到EAGAIN出現,但是如果返回值0的話,並不會出現EAGAIN。

建議你還是多用strace來查詢問題所在,有時候比gdb更能直接找出原因。

還有再糾正一點,recv是一個linux系統調用,要麼是阻塞要麼是返回,不存在死循環的問題的, 死循環肯定是出在你的程序代碼中。 如果你覺得recv本身不退出又佔用大量cpu,那就是linux庫出bug或者是內核bug了。

閱讀全文

與linuxrecv函數相關的資料

熱點內容
迷你編程登錄迷你號驗證碼是什麼 瀏覽:398
做數據表如何打出平方 瀏覽:447
在vmos下載的文件路徑在哪 瀏覽:771
有什麼購物app是用微信支付的 瀏覽:99
數控編程中夾持什麼意思 瀏覽:295
文件夾能容納多少張截圖 瀏覽:85
視頻文件查找 瀏覽:786
如何進入java的編程界面 瀏覽:371
二級開發者還有哪些app 瀏覽:241
app充值請聯系itunes 瀏覽:678
矢量app和cdr哪個好 瀏覽:85
系統文件壞了如何修復 瀏覽:20
鍵盤系統文件誤刪 瀏覽:738
白金英雄壇所有版本 瀏覽:842
ps文件轉hsj 瀏覽:382
哪個網站電影 瀏覽:490
ps4游戲文件格式名稱 瀏覽:290
caxa教程2007 瀏覽:832
新點是什麼小說網站 瀏覽:753
魔獸世界冰封王座3版本轉換器 瀏覽:418

友情鏈接