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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux - send 出现 Resource temporarily unavailable

發(fā)布時(shí)間:2023/12/16 linux 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux - send 出现 Resource temporarily unavailable 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.前言

主機(jī)和AI設(shè)備通訊時(shí)候,通過send發(fā)送小數(shù)據(jù),發(fā)送和接受都正常。可是發(fā)送YUV數(shù)據(jù)時(shí)候,一幀720P數(shù)據(jù)大概1.3M左右,發(fā)送時(shí)候就會報(bào)錯(cuò)Resource temporarily unavailable錯(cuò)誤,只發(fā)送了一幀的部分?jǐn)?shù)據(jù),導(dǎo)致該幀數(shù)據(jù)不完整,無法使用。通過錯(cuò)誤碼查找,是由于發(fā)送緩存池滿導(dǎo)致的。

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函數(shù)的過程是將應(yīng)用程序請求發(fā)送的數(shù)據(jù)拷貝到發(fā)送緩存中發(fā)送并得到確認(rèn)后再返回.但由于發(fā)送緩存的存在,表現(xiàn)為:如果發(fā)送緩存大小比請求發(fā)送的大小要大,那么send函數(shù)立即返回,同時(shí)向網(wǎng)絡(luò)中發(fā)送數(shù)據(jù);否則,send向網(wǎng)絡(luò)發(fā)送緩存中不能容納的那部分?jǐn)?shù)據(jù),并等待對端確認(rèn)后再返回(接收端只要將數(shù)據(jù)收到接收緩存中,就會確認(rèn),并不一定要等待應(yīng)用程序調(diào)用recv);
??????在非阻塞模式下,send函數(shù)的過程僅僅是將數(shù)據(jù)拷貝到協(xié)議棧的緩存區(qū)而已,如果緩存區(qū)可用空間不夠,則盡能力的拷貝,返回成功拷貝的大小;如緩存區(qū)可用空間為0,則返回-1,同時(shí)設(shè)置errno為EAGAIN.

? ? ?當(dāng)客戶通過Socket提供的send函數(shù)發(fā)送大的數(shù)據(jù)包時(shí),就可能返回一個(gè)EGGAIN的錯(cuò)誤。該錯(cuò)誤產(chǎn)生的原因是由于send函數(shù)中的size變量大小超過了tcp_sendspace的值。tcp_sendspace定義了應(yīng)用在調(diào)用send之前能夠在kernel中緩存的數(shù)據(jù)量。當(dāng)應(yīng)用程序在socket中設(shè)置了O_NDELAY或者O_NONBLOCK屬性后,如果發(fā)送緩存被占滿,send就會返回EAGAIN的錯(cuò)誤。

解決方法:

? ? ?1)在調(diào)用send前,在setsockopt函數(shù)中為SNDBUF設(shè)置更大的值

? ? ? ? ?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,因?yàn)閣rite沒有設(shè)置O_NDELAY或者O_NONBLOCK

代碼如下:

采用write并分包發(fā)送策略?

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);/**發(fā)送區(qū)為滿時(shí)候循環(huán)等待,直到可寫為止*/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;}

?

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。