首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > VxWorks >

vxworks下send和recv的有关问题

2013-04-02 
vxworks下send和recv的问题小弟最近做了一个东西,两个设备在通信协议后,会各自创建两个线程,一个发送,一个

vxworks下send和recv的问题
小弟最近做了一个东西,两个设备在通信协议后,会各自创建两个线程,一个发送,一个接收,一个设备称为A,一个设备称为B,A和A进行通信时,一切正常,A和B通信后,会出现通信暂时中断的现象。我设置的socket缓冲为8000,每次在发送数据时,先发送8字节的数据头,再发送1600字节的数据,也就是说socket缓冲大约能暂时存放5帧数据。现在出现的问题是,B设备会recv延时,并且recv先延时,继而send在添满5帧数据后,也会阻塞,继而send延时,B设备一般在开始一分钟后开始延时,不断延时18tick(60tick==1S)左右,间断会出现一秒乃至两秒的延时,已经查问题好几天了,块崩溃了,求帮助,现附B设备代码(估计A设备正常):

/*接收数据*/
void vpmRecDMTask(int sock)
{
int iRet;
int iLen = 0;
int iRecLen = 0;
int i=0;
int oldTick = 0;
int newTick = 0;
int seq = 0;/*wangzq*/
VPM_AUDIO_DATA_HEAD headMsg;
VPM_NEGOTIATION_INFO stNegotiationInfo;
VPM_AUDIO_DATA_MSG audioMsg;
memset(&headMsg, 0, sizeof(VPM_AUDIO_DATA_HEAD));
memset(&stNegotiationInfo, 0, sizeof(stNegotiationInfo));


while(1)
{
iLen = 0;
seq ++;
iRecLen = sizeof(VPM_AUDIO_DATA_HEAD);
oldTick = tickGet();
while(1)
{
iRet = recv(sock, (char*)&headMsg+iLen, iRecLen, 0);/*接收数据头*/
if(iRet==0 || (iRet==ERROR))
{
printf("中队收到的数据头失败,准备退出\r\n");
goto DMClose;
}
iLen += iRet;
iRecLen -= iRet;

/*检测数据头,防止有错误的数据*/
if(iLen == sizeof(VPM_AUDIO_DATA_HEAD))
{
break;
}

}
newTick = tickGet();
if((newTick-oldTick) > 6)
printf("recv1:newTick-oldTick: %d-%d=%d;seq:%d\r\n", newTick,oldTick,newTick-oldTick,seq);
/*检查数据头,排除错误的语音数据;
若不是数据头,则检查对方发送的信息,看是否是通话被抢占信息*/
if(headMsg.sendDataCount != VPM_AUDIO_RECVBUF_SIZE)/*查看接下来即将发送的一帧数据是否为指定的数据*/
{
printf("headMsg.sendDataCount != VPM_AUDIO_RECVBUF_SIZE!\n");
memcpy(&stNegotiationInfo, &headMsg, sizeof(VPM_AUDIO_DATA_HEAD));
if(stNegotiationInfo.ulHead != VPM_NEGOTIATION_MSG_HEAD)
{
printf("无效数据,重新接收数据头\r\n");
continue;
}
/*对端设备被抢占*/
if(stNegotiationInfo.ulMsg == VPM_AUDIO_DEAL_GRAB)
{
printf2screen0(gm_stShowInfo[VPM_AUDIO_SHOW_STATUS_GRAB].pszDescription);
printf("vpmRecDMTask exit because of GRAB!\r\n");
taskDelay(5*60); 
    goto DMClose;
}
}


iLen = 0;
iRecLen = VPM_AUDIO_RECVBUF_SIZE;
oldTick = tickGet();
while(1)
{
iRet = recv(sock, &vpmAudTxbuf[vpmAudTxbufIndex][iLen], iRecLen, 0);/*接收语音数据*/

if((ERROR == iRet) || (0 == iRet))
{
printf("中队收到的数据包失败,准备退出\r\n");
    goto DMClose;
}

iLen += iRet;
iRecLen -= iRet;

if(iLen == VPM_AUDIO_RECVBUF_SIZE)
{
break;
}
}
newTick = tickGet();
if((newTick-oldTick) > 6)
printf("recv2:newTick-oldTick: %d-%d=%d;seq:%d\r\n", newTick,oldTick,newTick-oldTick,seq);
/*发送语音数据到队列gm_vpmAudioDataRecQue,在vpmAudioRecvTask中会接收信息并播放*/
/*memcpy(vpmAudTxbuf[vpmAudTxbufIndex], audioBuf, VPM_AUDIO_RECVBUF_SIZE);*/
audioMsg.Index = vpmAudTxbufIndex;
msgQSend(gm_vpmAudioDataRecQue, (void *)&audioMsg, sizeof(VPM_AUDIO_DATA_MSG), NO_WAIT,  MSG_PRI_NORMAL);
vpmAudTxbufIndex++;
vpmAudTxbufIndex &= VPM_AUDIO_FRAME_NUM-1;

}



DMClose:
printf("vpmRecDMTask exit !\r\n");


close(sock);
semTake(gm_semAudioSockFlag, WAIT_FOREVER);
sockFlag = TRUE;/*若对方关闭对话,则sockFlag置TRUE,以便于通知vpmDealFun2里的检测循环退出*/
semGive(gm_semAudioSockFlag);
taskDelay(30);

}



/*发送数据*/
void vpmSendDMTask(int sock)
{
int iRet;
int iLen = 0;
int iRecLen = 0;
int oldTick,newTick;
VPM_AUDIO_MAIN_MSG stMessage;
VPM_AUDIO_DATA_HEAD headMsg;/*发送数据头*/
VPM_AUDIO_DATA_MSG dataMessage;/*用来从gm_vpmAudioDataSendQue队列中接收音频数据,用来通过网络进行发送*/
extern int g_currentSocket4serverpush[];        /*当前监测Socket的下标索引*/


memset(&stMessage, 0, sizeof(VPM_AUDIO_MAIN_MSG));
memset(&headMsg, 0, sizeof(VPM_AUDIO_DATA_HEAD));
g_currentSocket4serverpush[0] = sock;/*检测sock发送是否超时*/

while(1)
{
/*接收音频数据,向机关发送*/
iRet = msgQReceive(gm_vpmAudioDataSendQue, (void *)&dataMessage, sizeof(VPM_AUDIO_DATA_MSG), WAIT_FOREVER);   
if(ERROR == iRet)
{
taskDelay(1);
continue;
}


headMsg.requestID = gm_iCurId;/*音频数据发送的目的ID*/
headMsg.sendDataCount = VPM_AUDIO_RECVBUF_SIZE;/*发送的音频数据的大小*/

httpPreSetMonitorPoint4push(1,60);/*设置监测点,若超时,则断开链接,超时时间为60*30 TICKS*/
oldTick = tickGet();
iRet = send(sock, &headMsg, sizeof(VPM_AUDIO_DATA_HEAD), 0);/*发送数据头*/
newTick = tickGet();
if((newTick-oldTick) > 6)
printf("send1:newTick-oldTick: %d-%d=%d\r\n", newTick,oldTick,newTick-oldTick);
if(iRet == 0 || (iRet == ERROR))
{
printf("网络出现问题,数据头没有发送成功\r\n");
httpPostSetMonitorPoint4push(1);/*取消超时检测*/
goto DMClose;

httpPostSetMonitorPoint4push(1);/*取消超时检测*/

httpPreSetMonitorPoint4push(1,60);/*设置监测点,若超时,则断开链接,超时时间为60*30 TICKS*/
{
oldTick = tickGet();
iRet = send(sock, vpmAudRxbuf[dataMessage.Index], headMsg.sendDataCount, 0);/*发送音频数据*/
newTick = tickGet();
if((newTick-oldTick) > 6)
printf("send2:newTick-oldTick: %d-%d=%d\r\n", newTick,oldTick,newTick-oldTick);
if(iRet == 0 || (iRet == ERROR))
{
printf("网络出现问题,数据包没有发送成功\r\n");
httpPostSetMonitorPoint4push(1);/*取消超时检测*/
goto DMClose;
}
httpPostSetMonitorPoint4push(1);/*取消超时检测*/
}
}
DMClose:
close(sock);
taskDelay(30);

}

[解决办法]
 recv 是阻塞方式还是非阻塞方式,怎么判断是接受问题 如果网络上有问题 可能数据就是慢
抓一下包看一下 数据的基本情况。
tcp windows窗口也有满的时候,流量控制,看一下是否影响。
[解决办法]
这种问题肯定是程序设计的问题,不可能是操作系统问题
[解决办法]
通信协议的实现为什么判断前几个字节?
第一个recv(怎么可以判断这里收到一定是头?)和第二个recv,也许对方一下子把头和内容一次发送过来呢?就是应用分开发,底层也可能拼包。
[解决办法]
把那个包的大小限制到1452以下试试,
[解决办法]
用任务来做,采用阻塞的方式接受,同时不要用printf换成logmsg,把goto换掉更好。
[解决办法]
会不会和任务优先级有关系?如果发送任务优先级比接收任务高,感觉就会出现这个现象。

热点排行