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++;
}