www.pudn.com > gps-time.rar > RegionSocket.cpp


// RegionSocket.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "RegionComm.h" 
#include "RegionSocket.h" 
#include "Communication.h" 
#include "comport.h" 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CRegionSocket 
 
CRegionSocket::CRegionSocket(CCommunication *m_pComm) 
{ 
    lSendCenterCount=0; 
	m_sServerName=""; 
	m_sConnectedAddress = ""; 
    m_ListenPort=8000; 
	m_IsConnected=FALSE; 
	m_bAskConnect = FALSE; 
	m_pOwner = m_pComm; 
	m_bRefuse = TRUE; 
} 
 
CRegionSocket::~CRegionSocket() 
{ 
 
} 
 
 
// Do not edit the following lines, which are needed by ClassWizard. 
#if 0 
BEGIN_MESSAGE_MAP(CRegionSocket, CAsyncSocket) 
	//{{AFX_MSG_MAP(CRegionSocket) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
#endif	// 0 
 
///////////////////////////////////////////////////////////////////////////// 
// CRegionSocket member functions 
//产生Socket 
BOOL CRegionSocket::CreateSocket() 
{ 
	if(CAsyncSocket::Create()) 
		return TRUE; 
	else 
		return FALSE;	 
} 
//连接 
BOOL CRegionSocket::Connect() 
{ 
   long ConnectError; 
    
   if(!CAsyncSocket::Connect(m_sServerName,m_ListenPort)) 
   { 
		   ConnectError=CAsyncSocket::GetLastError(); 
		   if (WSAEWOULDBLOCK == ConnectError) 
				return TRUE; 
		   else 
		   { 
               m_nErrorType=ERR_BAD; 
			   m_dwErrorCode=ConnectError; 
		       ProcessError(ERR_BAD,ConnectError); 
		       return(FALSE); 
		   } 
   }    
   return(TRUE); 
} 
//响应Socket连接事件 
void CRegionSocket::OnConnect(int nErrorCode)  
{	 
	if (0 != nErrorCode) 
   { 
      switch( nErrorCode ) 
      { 
         case WSAEADDRINUSE:  
            //AfxMessageBox("地址已被使用\n");			  
            break; 
         case WSAEADDRNOTAVAIL:  
            //AfxMessageBox("本机没有该地址\n"); 
            break; 
         case WSAEAFNOSUPPORT:  
            //AfxMessageBox("此类地址不能用于该类Socket\n"); 
            break; 
         case WSAECONNREFUSED:  
            //AfxMessageBox("连接被强制中止\n"); 
			 CAsyncSocket::Connect(m_sServerName,m_ListenPort); 
            break; 
         case WSAEDESTADDRREQ:  
            //AfxMessageBox("需要一个目的地址才能连接\n"); 
            break; 
         case WSAEFAULT:  
            //AfxMessageBox("地址长度字节不正确!\n"); 
            break; 
         case WSAEINVAL:  
            //Socket地址被正确绑定 
            break; 
         case WSAEISCONN:  
            //Socket连接成功 
            break; 
         case WSAEMFILE:  
            //AfxMessageBox("文件描述字已被用完\n"); 
            break; 
         case WSAENETUNREACH:  
            //AfxMessageBox("目的主机不能到达\n"); 
			 CAsyncSocket::Connect(m_sServerName,m_ListenPort); 
            break; 
         case WSAENOBUFS:  
            //AfxMessageBox("缓冲区用完,不能建立连接\n"); 
            break; 
         case WSAENOTCONN:  
            //Socket没有连接 
            break; 
         case WSAENOTSOCK:  
            //文件描述字不是一个Socket 
            break; 
         case WSAETIMEDOUT:  
            //连接超时			  
			 CAsyncSocket::Connect(m_sServerName,m_ListenPort); 
            break; 
         default:			           
            break; 
      }      	   
   } 
	else 
	{ 
		 m_IsConnected=TRUE;		 
		 RegisterRegionNo();				  
	} 
	CAsyncSocket::OnConnect(nErrorCode);	 
} 
//响应Socket关闭事件 
void CRegionSocket::OnClose(int nErrorCode)  
{	 
	CAsyncSocket::OnClose(nErrorCode); 
	CAsyncSocket::Close(); 
	//if (nErrorCode!=0) 
	//{ 
		m_pOwner->Degrade(); 
	//} 
	if (true) //nErrorCode == 0 && m_bRefuse    ?? by lv cange 
	{ 
		m_IsConnected=FALSE; 
		m_bAskConnect = FALSE;		 
		AfxGetMainWnd()->PostMessage(WM_COMMAND, IDM_CONNECTOK, (LPARAM)MAKELONG(0,MAKEWORD(0,DEVTYPE_SERVERSOCKET))); 
		 
		if (CreateSocket())  
		{ 
		     Connect();			 
		}  
		else 
		{ 
		    m_dwErrorCode = nErrorCode; 
		    m_nErrorType = ERR_REPARABLE; 
		    ProcessError(ERR_REPARABLE,nErrorCode); 
		} 
	} 	 
} 
//响应Socket接收事件 
void CRegionSocket::OnReceive(int nErrorCode)  
{ 
	// TODO: Add your specialized code here and/or call the base class 
    if(ReadData()>0) 
		ProcessTable(); 
	CAsyncSocket::OnReceive(nErrorCode); 
} 
//读数据 
int CRegionSocket::ReadData() //读取数据并放入通信缓冲区 
{ 
//     BYTE TmpBuffReadData[m_MaxTableLen];//256 change to 300 
	 int  datLength,TotalLength; 
	 if(!m_IsConnected) 
		 return(0); 
	 TotalLength=0; 
	 datLength=CAsyncSocket::Receive(TmpBuffReadData,m_MaxTableLen);//256 
	 while(datLength>0) 
	 {    
		 TotalLength=TotalLength+datLength; 
		 MyNetBuff.SaveBuff(TmpBuffReadData,datLength); 
		 datLength=CAsyncSocket::Receive(TmpBuffReadData,m_MaxTableLen); //256 
	 } 
	 return(TotalLength); 
} 
 
//由该过程来处理从中心网络来的数据,具体通信协议由该过程来处理 
void CRegionSocket::ProcessTable() //处理接收到的通信表格  
{ 
     //此处要引用串口通信类指针pAllCom 
//	BYTE  rBuff[m_MaxTableLen]; 
	 int  rCount; 
	 //ReadData(); 
 
} 
//发送未打包的表格。首先打包再发送 
BOOL CRegionSocket::SendTable(BYTE *tabBuff, int tabCount) 
{ 
	//lv test 060808 
	long ltime,ltime2; 
	ltime=GetTickCount(); 
 
//     BYTE TmpBuff[m_MaxTableLen]; 
	 int i,packLength; 
 
	 if(!m_IsConnected) 
		 return(FALSE); 
	 if(tabCount>m_MaxTableLen) 
		 return(FALSE); 
	 for(i=0;i0) 
     { 
		 CAsyncSocket::Send(TmpBuff,packLength); 
 
		 //lv test 060808 
		 ltime2=GetTickCount(); 
		 ltime=ltime2-ltime; 
		 if(ltime>10) 
			 TRACE("CRegionSocket::SendTable time %dms",ltime); 
 
		 return(TRUE); 
	 } 
	 else 
	 { 
		 TRACE("CRegionSocket::SendTable FALSE"); 
		 return(FALSE); 
	 } 
} 
//设置区域时间 
BOOL CRegionSocket::SetRegionTime(BYTE *szData) 
{ 
	SYSTEMTIME st;  
 
	st.wYear = szData[5]*256+szData[6]; 
	st.wMonth = szData[7]; 
	st.wDay = szData[8]; 
	st.wHour = szData[9]; 
	st.wMinute = szData[10]; 
	st.wSecond = szData[11]; 
	st.wMilliseconds = 0; 
	st.wDayOfWeek = 0; 
 
	return SetLocalTime(&st); 
 
} 
 
//区域向中心登记 
void CRegionSocket::RegisterRegionNo() 
{ 
 
	BYTE sBuff[6]; 
     sBuff[0]=0; 
	 sBuff[1]=6; 
	 sBuff[2]=RegionNo; 
	 sBuff[3]=CtrlLinkCode; 
	 sBuff[4]=RegistRegionNo; 
	 sBuff[5]=m_pOwner->m_cRegionNo; 
	 SendTable(sBuff,6); 
} 
 
//发送设备状态 
void CRegionSocket::NotifyLineStatusTab(BYTE sDeviceType, BYTE sDeviceNo,BOOL IsConnected) 
{ 
	BYTE sBuff[8]; 
	if(!m_bAskConnect) 
		return; 
     sBuff[0]=0; 
	 sBuff[1]=8; 
	 sBuff[2]=RegionNo; 
	 sBuff[3]=CtrlLinkCode; 
	 sBuff[4]=NotifyLineStatus; 
	 sBuff[5] = sDeviceType; 
	 sBuff[6] = sDeviceNo; 
	 if(IsConnected) 
		 sBuff[7] = 1; 
	 else 
		 sBuff[7] = 0; 
	 SendTable(sBuff,8); 
 
} 
//关闭Socket 
BOOL CRegionSocket::CloseSocket() 
{ 
	if (m_hSocket != INVALID_SOCKET)  
	{ 
		AsyncSelect(0); 
		Close(); 
	} 
	m_IsConnected = FALSE; 
	return TRUE;	 
} 
//修改服务器名、端口号 
BOOL CRegionSocket::UpdateProperty(CString sName, long nPort,CString sIPAddr) 
{ 
	if((sName ==m_sServerName) &&  ((UINT)nPort ==m_ListenPort)  && (sIPAddr ==m_sConnectedAddress)) 
		return FALSE; 
	m_ListenPort = nPort; 
	m_sServerName = sName; 
	m_sConnectedAddress = sIPAddr; 
	CloseSocket(); 
	m_hSocket = INVALID_SOCKET; 
	CreateSocket(); 
	Connect(); 
	return TRUE; 
} 
 
void CRegionSocket::ProcessError(int m_nErrorType,DWORD m_dwErrorCode) 
{ 
	switch (m_nErrorType) { 
	case ERR_BAD: 
		m_bAskConnect = FALSE; 
		if (m_IsConnected) { 
			if (m_hSocket != INVALID_SOCKET) { 
				AsyncSelect(0); 
				Close(); 
			} 
			m_IsConnected = FALSE; 
		} 
		break; 
	case ERR_REPARABLE: 
		m_bAskConnect = FALSE; 
		if (m_hSocket != INVALID_SOCKET) { 
			AsyncSelect(0); 
			Close(); 
		} 
		m_IsConnected = FALSE; 
		if (CreateSocket()) { 
			if (!Connect()) 
			 { 
				AsyncSelect(0); 
				Close(); 
			} 
		} 
		break; 
	case ERR_OCCURRENT: 
		break; 
	}	 
	AfxGetMainWnd()->PostMessage(WM_COMMAND, IDM_OCCURERROR, (LPARAM)this); 
} 
 
void CRegionSocket::SendCenter() 
{ 
	if(!m_bAskConnect) 
		return; 
	BYTE sBuff[5]; 
	 
	sBuff[0]=0; 
	sBuff[1]=5; 
	sBuff[2]=RegionNo; 
	sBuff[3]=CtrlLinkCode; 
	sBuff[4]=QueryCenterStatus; 
	 
	SendTable(sBuff,5); 
	if (lSendCenterCount>3) 
	{ 
		//路口降级 
		lSendCenterCount=-1; 
		m_pOwner->Degrade(); 
		m_IsConnected=FALSE; 
	} 
	else 
	{ 
		if (lSendCenterCount!=-1) 
			lSendCenterCount=lSendCenterCount+1; 
	} 
}