Click here to Skip to main content
15,900,589 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
when the recv function in client return WSAECONNRESET error,I try connect the server again.But it always failed.Who
can help me solve the error of WSAECONNRESET in client.Thanks


C++
/**
* receive a packet from souce,then enter it into queue
* @brief 供ctrl起线程调用,出错时上报错误码
* @param[OUT] pstDataPacket 。
* @return 参考CISourceFilter::readDataPacket注释。
*/
ULONG CMsgMutualTcp::receiveMsg(CMsgData &stMsgData)
{
	/* 收包的返回值 */
	LONG lRecvLen = -1;

	ULONG ulRet = ERR_COMMON_FAIL;

	/* 判断tcp连接是否已经创建,如果没有创建则创建tcp连接 */
	if (BOOL_FALSE == m_bTcpConEstablished)
	{
		ulRet = createTcpConnect();
		switch (ulRet)
		{
			/* 表示连接tcp成功 */
		case ERR_COMMON_SUCCEED:
			{
				m_bTcpConEstablished = BOOL_TRUE;
				m_bReBldSocketStatus = BOOL_FALSE;
				setKeepLive();
				return ERR_COMMON_SUCCEED;
			}
		case ERR_RECEIVE_MEDIA_TIMEOUT:
			{
				//   Sleep(50);
				/* 表示超时没有创建tcp链接,属于正常情况 */
				return ERR_RECEIVE_MEDIA_TIMEOUT;
			}
		default:
			{
				/* 在创建tcp连接过程中产生了错误 */
				FRAME_writeLog("CMsgMutualTcp::receiveMsg",__LINE__,"failed to create tcp connect.\n");
				return ERR_COMMON_FAIL;
			}
		}
	}


	if (0 == m_ulKeepLiveTimerID)
	{
		/* 启动一个定时器定时发送引流包 */
		FRAME_writeLog("CMsgMutualTcp::receiveMsg",__LINE__," start sending msg pkt timer.\n");

		m_stLiveMsg.stMsgHdr.usMessageFlag = MSG_VMP_DATA_HEAD_FLAG;
		m_stLiveMsg.stMsgHdr.ucVersion = 2;  //版本号, 统一填2
		m_stLiveMsg.stMsgHdr.ucSubVersion = 0; //子版本号, 统一填0
		m_stLiveMsg.stMsgHdr.ucType = 0;   //0表示请求消息
		m_stLiveMsg.stMsgHdr.usCommand = VMP_MSG_USER_KEEPLIVE;  //待定
		m_stLiveMsg.stMsgHdr.usStatus = 0;  //
		m_stLiveMsg.stMsgHdr.ulSeqNum = sequencePlus();  //待定
		m_stLiveMsg.stMsgHdr.ulSrcModId = 0;  //
		m_stLiveMsg.stMsgHdr.ulDstModId = 0;  //待定
		m_stLiveMsg.stMsgHdr.ulFromHandle = 0;  //
		m_stLiveMsg.stMsgHdr.ulToHandle = 0;  //待定
		m_stLiveMsg.stMsgHdr.ulContentLength = sizeof(IE_USER_LOG_INFO_S);  //vmp消息的总长度
		m_stLiveMsg.stMsgHdr.ucFeature = 0;  //小端模式
		m_stLiveMsg.stUserLogInfo.stIEHdr.usIEID = IE_USER_LOG_INFO;
		m_stLiveMsg.stUserLogInfo.stIEHdr.usIEBodyLen = sizeof(IE_USER_LOG_INFO_S) - sizeof(VMP_IE_HEADER_S);
		strncpy(m_stLiveMsg.stUserLogInfo.szUserName, m_strUserName.c_str(), (sizeof(m_stLiveMsg.stUserLogInfo.szUserName) - 1));
		m_stLiveMsg.stUserLogInfo.ulUserLoginHandle = m_ulLoginID;
		m_stLiveMsg.stUserLogInfo.stUserLoginIP.usDomainType = MSG_AF_INET;
		m_stLiveMsg.stUserLogInfo.stUserLoginIP.ulIpv4Addr = m_ulLocalIP;

		m_stTimerParam.hSocket = m_hSocket;
		m_stTimerParam.ulDstIP = m_ulSrcIP;
		m_stTimerParam.usDstPort = m_usSrcPort;
		sendKeepLivePktCallback(this);

		m_ulKeepLiveTimerID = UWARE_XP_StartIndependTimer(OCX_KEEPLIVE_PACKET_SEND_INTERVAL,
			sendKeepLivePktCallback,
			this);
		if (0 == m_ulKeepLiveTimerID)
		{
			m_ucLiveFailCount = MSG_LIVE_FAIL_COUNT;
			FRAME_writeLog("CMsgMutualTcp::receiveMsg",__LINE__," startIndependTimer return error.\n");

			return ERR_COMMON_FAIL;
		}

		sendBookNotifyPkt();
	}

	if (OCX_INVALID_HANDLE == m_hSocket)
	{
		FRAME_writeLog("CMsgMutualTcp::receiveMsg",__LINE__,"invalid handle of socket\n");
		return ERR_COMMON_INVALID_PARAM;
	}

	OCX_POLLFD_S stPollFD = {0};
	stPollFD.lFd = (LONG) m_hSocket;
	stPollFD.usEvents = POLLIN;
	stPollFD.usRevents = 0;

	LONG lRet = OCX_poll(&stPollFD, 1, OCX_NETSTREAM_TIMEOUT_MAX);
	if (0 == lRet)
	{
		if (0 == g_tick)
		{
			g_tick = GetTickCount();
		}
		else
		{
			if (GetTickCount() - g_tick > 30000)
			{
				ulRet = retryConnectServer();
				if ( ERR_COMMON_SUCCEED == ulRet)
				{
					g_tick = 0;
					m_bConnenctStatus = BOOL_TRUE;
					FRAME_writeLog("CMsgMutualTcp::sendKeepLivePktCallback",__LINE__,"The RetryConnect has succeeded.\n");
				}
				else
				{
					m_bConnenctStatus = BOOL_FALSE;
					//FRAME_writeLog("CMsgMutualTcp::sendKeepLivePktCallback",__LINE__,"The RetryConnect has failed.\n");
				}
			}
		}

		//OCX_MPM_LOG1(UWARE_DEBUG, ERR_MPM_RECEIVE_MEDIA_TIMEOUT, "%s poll time out.", STR_PORT_ID(m_ulChannelID));
		return ERR_COMMON_FAIL;
	}
	else if (0 > lRet)
	{
		FRAME_writeLog("CMsgMutualTcp::receiveMsg",__LINE__,"poll failed, system errcode is %ld, handled as time out.\n", GetLastError());
		/* begin add by shiyouhua04562 VVD58736 */
		(VOID)Sleep(OCX_NETSTREAM_TIMEOUT_MAX);
		/* end add by shiyouhua04562 VVD58736 */

		return ERR_COMMON_FAIL;
		/* END: Modified by jinqifeng 06715, 2010/3/15   问题单号:VVD54479 */
	}

	g_tick = 0;

	m_stRecvAddr.sin_family  = AF_INET;
	m_stRecvAddr.sin_addr.s_addr = m_ulSrcIP;
	m_stRecvAddr.sin_port = m_usSrcPort;

	/* 从指定的socket上接收媒体数据 */
	lRecvLen = recv(m_hSocket, (CHAR *)stMsgData.aucBuffer, stMsgData.lDataLength, 0);
	if (0 == lRecvLen)
	{
		FRAME_writeLog("CMsgMutualTcp::receiveMsg",__LINE__,"Client connecttion closed");
		//ULONG retryStatus = retryConnectServer();		
		return ERR_COMMON_FAIL;
	}
	else if(SOCKET_ERROR == lRecvLen)
	{
		DWORD errCode = GetLastError();
		FRAME_writeLog("CMsgMutualTcp::receiveMsg",__LINE__,"recv is fail  %ld\n", errCode);
		ULONG retryStatus = retryConnectServer();

		if ( ERR_COMMON_SUCCEED == retryStatus)
		{
			Sleep(10);
			m_bConnenctStatus = BOOL_TRUE;
			FRAME_writeLog("CMsgMutualTcp::sendKeepLivePktCallback",__LINE__,"The RetryConnect has succeeded.\n");
		}
		else
		{
			m_bConnenctStatus = BOOL_FALSE;
			FRAME_writeLog("CMsgMutualTcp::sendKeepLivePktCallback",__LINE__,"The RetryConnect has failed.\n");
		}
		return ERR_COMMON_FAIL;
	}
	else
	{
		/* 先设置包的大小,否则校验引流报文错误 */
		stMsgData.lDataLength = lRecvLen;
	}

	return ERR_COMMON_SUCCEED;
}
Posted
Updated 25-Jun-14 17:20pm
v3
Comments
Jochen Arndt 25-Jun-14 5:59am    
The connection has been closed by the server for some reason. When the problem on the server side still exists establishing a new connection will of course fail.
Member 10066883 25-Jun-14 8:26am    
In order to simulate the environment, I pulled the network cable for a few seconds and then insert it.So i think the server is well.
Jochen Arndt 25-Jun-14 8:58am    
At first a hint:
Use the Reply button (right of a posters name) to reply to a comment. Than the poster will get an mail notification.

If you drop a connection by interrupting the physical connection, bost sides must detect this and handle appropiate. This means that all stale sockets should be closed and reopened. For the server side this includes cancelling pending listen operations and performing a new listen with a newly opened socket when the server lost his network connection (e.g. by unplugging the server's network cable).

Overall:
- If the server lost his network connection, it must be restarted.
- Check if the server detects that the connection has been lost.
This may be not detected in time when the client went away.
- The server may accept multiple connections and drop stale connections
after a specific time of inactivity.
Member 10066883 25-Jun-14 9:10am    
Thanks very much,but i can not quite understand what you mean.Because the server and clients are in the same LAN.I just pulled the network cable connected to my computer.Other clients communicate with the server remains normal
Jochen Arndt 25-Jun-14 9:43am    
When you disconnect your client, the server has a stale connection that is blocking further connections when it does not support multiple connections at the same time.

A server should detect such stale connections. This is usually done using a timer that is reset with each received data packet. When the timer expires, the server will close the connection. If your server allows only one client to be connected, you must then wait this time until the client can reconnect. The common solution to this problem is accepting multiple connections.

You said that other clients are still working. So I think that your server supports multiple connections and the problem is probably located in your client.

When unplugging a network cable and reinserting it, you should always wait some time to ensure that the network connection is up again. You can check this on the command line with 'ipconfig'.

Did you tried to terminate and restart your client application afterwards? When it then works the problem is definitely in your client app.

Another possible source is that your server acepts only one connection per client. Then the stale connection blocks the reconnect until the old connection is closed by the server.

As you see there many possible sources for your problem. To get better help you may add more information to your question using the green 'Improve' link.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900