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

TCP socket读数据的时候经常返回10035的异常

2012-11-10 
TCP socket读数据的时候经常返回10035的错误。我使用TCP协议来传送每秒15帧的视频数据(每帧大小约为70KB,每

TCP socket读数据的时候经常返回10035的错误。
我使用TCP协议来传送每秒15帧的视频数据(每帧大小约为70KB,每秒大约1MB的数据),接收端使用select IO模型,当有数据可读的时候从套接口读数据。socket的接收缓冲区修改为2Mb

但是读的时候经常返回10035的错误,大家帮忙分析一下,谢谢了!
发送端对TCP的socket进行了select判断,为可读后再发送。
类似这种大数据量的TCP发送数据,大家一般是如何发送和接收的呢? 
代码如下,不是很好理解,让你们费心了,再次感谢.
  memset(g_pRecvBuf, 0, MAXRECVBUFLEN); //g_pRecvBuf是接收区,大小为1Mb 0x100000
long lMsgSize;
int iLen = recv((*iter)->m_pComm->m_fdSocket, (char *)&lMsgSize, sizeof(long), 0);
if((iLen <= 0)||(lMsgSize < 0))
{
if(lMsgSize < 0)
{
RUNFILELOG(TLogLevel_Debug, "recv msg error: video data size < 0 .");

}
(*iter)->m_pComm->closeSocket();
DELETE_P((*iter)->m_pComm);
TMainCtrl::instance()->getXlwSimEntity()->m_bConnect = false; //断链,需要重连
RUNFILELOG(TLogLevel_Debug, "Socket Error and ReConnect.");
return ;

}
OspPrintf(TRUE, FALSE, "video data size %d \n", lMsgSize);
int bytes_read = 0; 
char *recvptr = NULL; 
int iCount = 0;
bytes_left = lMsgSize; 
recvptr = g_pRecvBuf;
int err = 0;
fd_set scanSet;

//扫描等待时间
struct timeval waitTime;
int begainRecvTime = time(NULL);
int currentRecvTime = begainRecvTime;
while(bytes_left > 0)//这里循环的接收。


currentRecvTime = time(NULL);
if(currentRecvTime - begainRecvTime > 1 || (iCount == 1 && bytes_read == 0))
{
RUNFILELOG(TLogLevel_Error, "There is no any receive data (bytes_left:%d total :%d) MaxRecvTimes:%d!", bytes_left, lMsgSize, MaxRecvTimes);
return; 
}
int fdSock =(*iter)->m_pComm->m_fdSocket;
bytes_read = recv(fdSock, recvptr, bytes_left, 0); 
if(bytes_read < 0) 
{
#ifdef _WIN32
err = WSAGetLastError();
if(WSAEWOULDBLOCK == err || WSAEINPROGRESS == err) 
#else
if ( (errno == EAGAIN) || ( errno == EINTR))
#endif
{
bytes_read = 0; //是否是错误? 或者因为循环的时候的确没有数据,是正常的情况?RUNFILELOG(TLogLevel_Debug, "recv data err %d.", err);
}
else//if(WSAETIMEDOUT == err || WSAENETDOWN == err)
{
(*iter)->m_pComm->closeSocket();
DELETE_P((*iter)->m_pComm);
TMainCtrl::instance()->getXlwSimEntity()->m_bConnect = false; //断链,需要重连
RUNFILELOG(TLogLevel_Debug, "Socket Error and ReConnect.");
}

else if(bytes_read == 0) 
{
#ifdef _WIN32
err = WSAGetLastError();
RUNFILELOG(TLogLevel_Error,"read (FD=%d) failed, errno=%d", fdSock, err);
#else
RUNFILELOG(TLogLevel_Error,"read (FD=%d) failed, err=%d", fdSock, errno);
#endif
}
bytes_left -= bytes_read; 
recvptr += bytes_read; 
iCount++;




发送端得代码。
while(bytes_left>0) 


currentSendTime = time(NULL);
if(currentSendTime - begainSendTime >= MaxSendTimes)
{
LOG_DEBUG(true, "Send Reach the max Time:%", MaxSendTimes);
return FALSE;
}
FD_ZERO(&scanSet);//初始化fd_set
FD_SET(fd_sock, &scanSet);//分配套接字句柄到相应的fd_set
waitTime.tv_sec = 0;
waitTime.tv_usec = 20*1000;

s32 select_ret = 0;

//判断可写(防止缓冲区爆满)
select_ret = select(FD_SETSIZE, (fd_set *)0, &scanSet, (fd_set *)0, &waitTime) ;
written_bytes = send(fd_sock, writePtr, bytes_left, 0);
if(written_bytes<=0) /* 出错了*/ 

#ifdef _WIN32  
int err = WSAGetLastError();
#else
int err = errno;
#endif
#ifdef _WIN32
if(err == WSAECONNABORTED || err == WSAEWOULDBLOCK || WSAEINPROGRESS == err)


#else
if(errno == EAGAIN || errno == EINTR) /* 中断错误 我们继续写*/ 
#endif
{
written_bytes=0; 
LOG_DEBUG(true, "send packet error.");
}
else /* 其他错误 没有办法,只好撤退了*/ 
{

//做一些处理
LOG_DEBUG(true, "socket error and stop send data.");
g_bSendVideo = false;

//return FALSE;
}

bytes_left -= written_bytes; 
writePtr += written_bytes; /* 从剩下的地方继续写 */ 
if(iCount > 1)
{
LOG_DEBUG(true, "send a frame more than one time");
}
iCount++;

}

[解决办法]
这是MS的解释。
【无法立即完成一个非阻止性套接字操作。】
[解决办法]
VS菜单中的Tools下面有个Error Lookup里面可以直接根据错误码查询的。
Mark下,漫漫看
[解决办法]
recv的时候返回10035很正常啊,IOCP就是用来解决大并发连接异步IO的问题的。
你投递了WSARECV之后,返回-1,并且WSAGetLastError=10035,说明这个异步IO已经投递到网络层了,只不过当前接收缓冲区内没有数据,需要网络层接收到数据之后,由操作系统通知你异步IO已经完成,即GetQueuedCompletionStatus。
[解决办法]
你也可以用阻塞的recv和send,就是会卡住所在的线程。
[解决办法]
异步处理的话 这个 10035可以忽略的
[解决办法]
select之后,好像没有对结果进行判断,是有可读或者可写等,而直接调用了send和recv。

[解决办法]

探讨

引用:
最近刚看了一本网络编程的书,帮你分析一下问题。
1. 第一个recv接收长度lMsgSize,潜在问题是如果到达的数据小于4个字节,是不正确的,最好判断收到4个字节后再往下走。
2. 第二个接收数据的recv,返回10035是正常的,因为对方的数据没有到达,错误码是WSAEWOULDBLOCK。解决方法:
2.1 用setsockopt(SO_RCVTIMEO)……

热点排行