日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux - send 出现 Resource temporarily unavailable

發布時間:2023/12/16 linux 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux - send 出现 Resource temporarily unavailable 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.前言

主機和AI設備通訊時候,通過send發送小數據,發送和接受都正常??墒前l送YUV數據時候,一幀720P數據大概1.3M左右,發送時候就會報錯Resource temporarily unavailable錯誤,只發送了一幀的部分數據,導致該幀數據不完整,無法使用。通過錯誤碼查找,是由于發送緩存池滿導致的。

2.代碼

int Send(int handle, unsigned char *buf, int len,int flags, const int selectSec, const int selectUsec) {int sendtotal = -1;int sendlen = 0;fd_set wset;struct timeval tv;FD_ZERO(&wset);FD_SET(handle, &wset);tv.tv_sec = selectSec / 1000000;tv.tv_usec = selectUsec % 1000000;int result = select(handle + 1, NULL, &wset, NULL, &tv);if ( result > 0){if (FD_ISSET(handle, &wset)){sendtotal = 0;while(sendtotal < len){sendlen = send(handle, (buf + sendtotal), (len - sendtotal) , flags);if(sendlen <= 0){perror("-----[send]----:");return -1;}sendtotal += sendlen;}}}else{perror("-----[select]----:");}return sendtotal; }

?

3.解決方法

? ? ? 在阻塞模式下,send函數的過程是將應用程序請求發送的數據拷貝到發送緩存中發送并得到確認后再返回.但由于發送緩存的存在,表現為:如果發送緩存大小比請求發送的大小要大,那么send函數立即返回,同時向網絡中發送數據;否則,send向網絡發送緩存中不能容納的那部分數據,并等待對端確認后再返回(接收端只要將數據收到接收緩存中,就會確認,并不一定要等待應用程序調用recv);
??????在非阻塞模式下,send函數的過程僅僅是將數據拷貝到協議棧的緩存區而已,如果緩存區可用空間不夠,則盡能力的拷貝,返回成功拷貝的大小;如緩存區可用空間為0,則返回-1,同時設置errno為EAGAIN.

? ? ?當客戶通過Socket提供的send函數發送大的數據包時,就可能返回一個EGGAIN的錯誤。該錯誤產生的原因是由于send函數中的size變量大小超過了tcp_sendspace的值。tcp_sendspace定義了應用在調用send之前能夠在kernel中緩存的數據量。當應用程序在socket中設置了O_NDELAY或者O_NONBLOCK屬性后,如果發送緩存被占滿,send就會返回EAGAIN的錯誤。

解決方法:

? ? ?1)在調用send前,在setsockopt函數中為SNDBUF設置更大的值

? ? ? ? ?intopt=SO_REUSEADDR;
? ? ? ? setsockopt(tcp_client_sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
??????????opt = 512*1024;
??????????int optlen = sizeof(int);
??????????setsockopt(tcp_client_sock,SOL_SOCKET,SO_SNDBUF,&opt,sizeof(int));
??????????getsockopt(tcp_client_sock,SOL_SOCKET,SO_SNDBUF,&opt,&optlen);?
  2).使用write替代send,因為write沒有設置O_NDELAY或者O_NONBLOCK

代碼如下:

采用write并分包發送策略?

int Send_YUV_Slice_Packet(int socket, unsigned char *data, unsigned int len) {/**分包策略省略*/{while (hasSndLen<packetlen){nRet = write(socket, sendBuf+hasSndLen, needSndLen);if (nRet <= 0){int errNo = errno;if ((nRet < 0) && ((errNo == EINTR) || (errNo == EAGAIN))){usleep(10*1000);/**發送區為滿時候循環等待,直到可寫為止*/continue;}else{printf("write Err, nRet=%d, errno=%d \n", nRet, errNo);return -1;}}else{hasSndLen += nRet;if (hasSndLen < packetlen){needSndLen = packetlen - hasSndLen;usleep(10*1000);}}} }return 0;}

?

總結

以上是生活随笔為你收集整理的Linux - send 出现 Resource temporarily unavailable的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。