Files
EF3-Interface/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.cpp
T
2014-11-11 20:02:14 +08:00

534 lines
17 KiB
C++

#include "StdAfx.h"
#include <WinDef.h>
#include <WinBase.h>
#include "So7_TCPIP.h"
const int WSA_MAJOR_VERSION = 1;
const int WSA_MINOR_VERSION = 1;
#define WSA_VERSION MAKEWORD(WSA_MAJOR_VERSION, WSA_MINOR_VERSION)
#define SOCKADDR_LEN sizeof(SOCKADDR_IN)
const BYTE CommHeader[]={0x46,0x49,0x4E,0x53};
const BYTE HandShaking[]={0x46,0x49,0x4E,0x53,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const BYTE DRW_SData[]={0x46,0x49,0x4E,0x53,0x00,0x00,0x00,0x1A,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x80,0x00,0x02,0x00,0x05,0x00,0x00,0x03,0x00,0xFF,0x01,0x01,0x82,0x00,0x0A,0x00,0x00,0x01};
const int DRW_SDataIndexDA1=20;
const int DRW_SDataIndexSA1=23;
const int DRW_SDataIndexCMD1=26;
const int DRW_SDataIndexCMD2=27;
const int DRW_SDataIndexAddr1=29;
const int DRW_SDataIndexAddr2=30;
const int DRW_SDataIndexCh1=32;
const int DRW_SDataIndexCh2=33;
const int DRW_SDataIndexData=34;
const int DRW_SDataCCLen=0x1A;
const int DRW_RSDataIndexBufSize1=6;
const int DRW_RSDataIndexBufSize2=7;
const int DRW_RDataIndexData=30;
const int DRW_RDataCCLen=0x16;
HANDLE CSo7_TCPIP::m_Thread_Id=NULL;
HANDLE CSo7_TCPIP::m_Thread_Mutex=NULL;
int CSo7_TCPIP::m_Thread_State=TCPIP_THREAD_PAUSED;
int CSo7_TCPIP::m_iReceiveMaxBufSize=1024;
int CSo7_TCPIP::m_iSendMaxBufSize=1024;
SOCKET CSo7_TCPIP::m_Socket=INVALID_SOCKET;
in_addr CSo7_TCPIP::m_SreverIPAddress;
in_addr CSo7_TCPIP::m_ClientIPAddress;
u_short CSo7_TCPIP::m_iServerPortNumber=static_cast<u_short>(0);
struct_so7_tcpip_buff CSo7_TCPIP::m_TCPIPBuf[lChannelSize];
struct_so7_tcpip_data CSo7_TCPIP::m_TCPIPData;
//================================================================
CSo7_TCPIP::CSo7_TCPIP()
{
m_hMsgWnd=NULL;
for (int i=0;i<lChannelSize;i++)
{
m_TCPIPBuf[i]._size = 0;
m_TCPIPBuf[i]._CompletedSize = 0;
m_TCPIPBuf[i]._save_send_cmd = 99;
m_TCPIPBuf[i]._buffer = (char *)malloc(TCPIP_MAX_BUFF_SIZE);
m_TCPIPBuf[i]._hProtoPending = false;
m_TCPIPBuf[i]._event = NULL;
};
m_TCPIPData.s_status._HandshakingSucceed=false;
m_TCPIPData.s_status._WriteDataCompleted=false;
m_TCPIPData.s_status._ReadDataCompleted=false;
m_TCPIPData.s_status._SendReturnCode=TCPIP_CONNECT_OK;
m_TCPIPData.s_status._RecvReturnCode=TCPIP_CONNECT_OK;
m_TCPIPData.s_recv_data._type=0;
m_TCPIPData.s_recv_data._DataSize=0;
m_TCPIPData.s_recv_data._lData=(long long *)malloc(TCPIP_MAX_DAT_SIZE);
}
//================================================================
CSo7_TCPIP::~CSo7_TCPIP()
{
DisConnect();
for (int i=0;i<lChannelSize;i++)
{
free(m_TCPIPBuf[i]._buffer);
m_TCPIPBuf[i]._buffer=NULL;
}
free(m_TCPIPData.s_recv_data._lData);
m_TCPIPData.s_recv_data._lData=NULL;
}
//================================================================
void CSo7_TCPIP::Create_Thread()
{
if (!m_Thread_Id)
{
m_Thread_State = TCPIP_THREAD_RUNNING;
m_TCPIPBuf[CH_SEND]._event = CreateEvent(NULL,FALSE,NULL,NULL);
m_Thread_Id = CreateThread((LPSECURITY_ATTRIBUTES)NULL,0,(LPTHREAD_START_ROUTINE)m_Thread,(LPVOID)this,0,NULL);
m_Thread_Mutex = CreateMutex(NULL,FALSE,NULL);
}
}
//================================================================
void CSo7_TCPIP::Exit_Thread()
{
m_Thread_State = TCPIP_THREAD_EXIT;
SetEvent(m_TCPIPBuf[CH_SEND]._event );
if(m_Thread_Id)
{
DWORD dwCode = STILL_ACTIVE;
while(dwCode == STILL_ACTIVE)
{
GetExitCodeThread(m_Thread_Id,&dwCode);
Sleep(1);
}
}
SetEvent(m_TCPIPBuf[CH_SEND]._event );
CloseHandle(m_TCPIPBuf[CH_SEND]._event );
m_Thread_State = TCPIP_THREAD_EXIT;
ReleaseMutex(m_Thread_Mutex);
CloseHandle(m_Thread_Mutex);
m_Thread_Id=NULL;
}
//================================================================
void CSo7_TCPIP::_do_single_threaded_tcpip_comm(bool _bWaitForRsponse)
{
while ((m_TCPIPBuf[CH_SEND]._hProtoPending == TRUE) || (m_TCPIPBuf[CH_RECV]._hProtoPending == TRUE))
{
ASSERT(0);
Sleep(3);
}
m_TCPIPBuf[CH_SEND]._hProtoPending = TRUE;
UNREFERENCED_PARAMETER(_bWaitForRsponse);
m_TCPIPBuf[CH_RECV]._hProtoPending = FALSE;
SetEvent(m_TCPIPBuf[CH_SEND]._event);
while ((m_TCPIPBuf[CH_SEND]._hProtoPending == TRUE) || (m_TCPIPBuf[CH_RECV]._hProtoPending == TRUE))
{
Sleep(3);
}
}
//================================================================
unsigned __stdcall CSo7_TCPIP::m_Thread(LPVOID pThis)
{
CSo7_TCPIP* _This = (CSo7_TCPIP*)pThis;
for(;;)
{
if(m_Thread_State == TCPIP_THREAD_EXIT)
ExitThread(0);
WaitForSingleObject(m_TCPIPBuf[CH_SEND]._event ,INFINITE);
switch(m_Thread_State)
{
case TCPIP_THREAD_RUNNING:
{
_This->SendBuffer();
break;
}
case TCPIP_THREAD_PAUSED:
{
break;
}
case TCPIP_THREAD_EXIT:
{
ExitThread(0);
break;
}
}
};
m_Thread_State=TCPIP_THREAD_EXIT;
ExitThread(0);
}
//================================================================
int CSo7_TCPIP::Init_Winsock()
{
int nRet;
static int first = TRUE;
if (first)
{
WSADATA stWSAData; /* WinSock DLL Info */
nRet = WSAStartup(WSA_VERSION, &stWSAData);
if (nRet)
{
return FALSE;
}
first = FALSE;
}
return TRUE;
}
//================================================================
TCPIP_RETURN_CODE CSo7_TCPIP::Connect(const HWND& _hWnd,const in_addr& _IPAddress,const u_short& _nPortNumber)
{
TCPIP_RETURN_CODE rCode=TCPIP_CONNECT_OK;
m_hMsgWnd=_hWnd;
m_iServerPortNumber=_nPortNumber;
int retVal(0), errorCode(0);
retVal=Init_Winsock();
if(!retVal)
{
return TCPIP_INIT_WINSOCK_ERROR;
}
// 创建套节字
m_Socket = socket(AF_INET, SOCK_STREAM, 0);
if(m_Socket == INVALID_SOCKET)
{
rCode=TCPIP_INVAILD_SOCKET;
}
else
{
Create_Thread();
// 设置socket为窗口通知消息类型
::WSAAsyncSelect(m_Socket, m_hMsgWnd,WM_SOCKET, FD_CONNECT | FD_CLOSE | FD_WRITE | FD_READ);
// 填写服务器地址信息
sockaddr_in remote;
m_SreverIPAddress = _IPAddress;
remote.sin_addr = _IPAddress;
remote.sin_family = AF_INET;
remote.sin_port = htons(m_iServerPortNumber);
// 连接到远程机
retVal=connect(m_Socket, (sockaddr*)&remote, sizeof(sockaddr));
if(retVal)
{
errorCode = WSAGetLastError();
rCode=(TCPIP_RETURN_CODE)errorCode;
}
GetHostIPAddr(m_ClientIPAddress);
}
return rCode;
}
//================================================================
TCPIP_RETURN_CODE CSo7_TCPIP::DisConnect()
{
if(m_Socket == INVALID_SOCKET)
{
return TCPIP_INVAILD_SOCKET;
}
closesocket(m_Socket);
m_Socket = INVALID_SOCKET;
m_ClearSendBuf();
Exit_Thread();
return TCPIP_CONNECT_OK;
}
//================================================================
TCPIP_RETURN_CODE CSo7_TCPIP::GetHostIPAddr(in_addr& _IPAddress)
{
static int first = TRUE;
if (first)
{
if(m_Socket == INVALID_SOCKET)
{
return TCPIP_INVAILD_SOCKET;
}
char HostName[100];
gethostname(HostName,sizeof(HostName));
hostent *pAddr;
pAddr=gethostbyname(HostName);
memcpy(&m_ClientIPAddress,pAddr->h_addr_list[0],sizeof(in_addr));
_IPAddress=m_ClientIPAddress;
first = FALSE;
}
_IPAddress=m_ClientIPAddress;
return TCPIP_CONNECT_OK;
}
//================================================================
TCPIP_RETURN_CODE CSo7_TCPIP::Handshaking()
{
WaitForSingleObject(m_Thread_Mutex, INFINITE);
m_ClearSendBuf();
m_TCPIPBuf[CH_SEND]._size=sizeof(HandShaking);
memcpy(m_TCPIPBuf[CH_SEND]._buffer,HandShaking,m_TCPIPBuf[CH_SEND]._size);
m_TCPIPBuf[CH_SEND]._buffer[m_TCPIPBuf[CH_SEND]._size-1]=m_ClientIPAddress.S_un.S_un_b.s_b4;
m_TCPIPBuf[CH_SEND]._save_send_cmd=TCPIP_CMD_HANDSHAKING;
m_Thread_State=TCPIP_THREAD_RUNNING;
_do_single_threaded_tcpip_comm();
ReleaseMutex(m_Thread_Mutex);
return m_TCPIPData.s_status._SendReturnCode;
}
//================================================================
TCPIP_RETURN_CODE CSo7_TCPIP::_Send_Cmd_Write_D_Data(const short& _Addr,short* _Data,int _DataSize)
{
if(m_Socket == INVALID_SOCKET)
{
return TCPIP_INVAILD_SOCKET;
}
WaitForSingleObject(m_Thread_Mutex, INFINITE);
m_ClearSendBuf();
memcpy(m_TCPIPBuf[CH_SEND]._buffer,DRW_SData,sizeof(DRW_SData));
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexDA1]=m_SreverIPAddress.S_un.S_un_b.s_b4;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexSA1]=m_ClientIPAddress.S_un.S_un_b.s_b4;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCMD1]=0x01;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCMD2]=0x02;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexAddr1]=(_Addr>>8) & 0x0ff;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexAddr2]=_Addr & 0x0ff;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCh1]=(_DataSize>>8) & 0x0ff;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCh2]=_DataSize & 0x0ff;
for (int i=0;i<_DataSize;i++)
{
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i]=(_Data[i]>>8) & 0x0ff;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i+1]=_Data[i] & 0x0ff;
}
short sTmpData(0);
sTmpData=static_cast<short>(DRW_SDataCCLen+2*_DataSize);
m_TCPIPBuf[CH_SEND]._buffer[DRW_RSDataIndexBufSize1]=(sTmpData>>8) & 0x0ff;
m_TCPIPBuf[CH_SEND]._buffer[DRW_RSDataIndexBufSize2]=sTmpData & 0x0ff;
m_TCPIPBuf[CH_SEND]._size=DRW_SDataIndexData+2*_DataSize;
m_TCPIPBuf[CH_SEND]._save_send_cmd=TCPIP_CMD_WRITE_D_DATA;
m_TCPIPData.s_status._WriteDataCompleted=false;
m_Thread_State=TCPIP_THREAD_RUNNING;
_do_single_threaded_tcpip_comm();
ReleaseMutex(m_Thread_Mutex);
return m_TCPIPData.s_status._SendReturnCode;
}
//================================================================
TCPIP_RETURN_CODE CSo7_TCPIP::_Send_Cmd_Read_D_Data(const short& _Addr,const short& _DataSize)
{
if(m_Socket == INVALID_SOCKET)
{
return TCPIP_INVAILD_SOCKET;
}
WaitForSingleObject(m_Thread_Mutex, INFINITE);
m_ClearSendBuf();
memcpy(m_TCPIPBuf[CH_SEND]._buffer,DRW_SData,sizeof(DRW_SData));
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexDA1]=m_SreverIPAddress.S_un.S_un_b.s_b4;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexSA1]=m_ClientIPAddress.S_un.S_un_b.s_b4;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCMD1]=0x01;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCMD2]=0x01;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexAddr1]=(_Addr>>8) & 0x0ff;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexAddr2]=_Addr & 0x0ff;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCh1]=(_DataSize>>8) & 0x0ff;
m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexCh2]=_DataSize & 0x0ff;
m_TCPIPBuf[CH_SEND]._size=DRW_SDataIndexData;
m_TCPIPBuf[CH_SEND]._save_send_cmd=TCPIP_CMD_READ_D_DATA;
m_TCPIPData.s_status._ReadDataCompleted=false;
m_Thread_State=TCPIP_THREAD_RUNNING;
_do_single_threaded_tcpip_comm();
ReleaseMutex(m_Thread_Mutex);
return m_TCPIPData.s_status._SendReturnCode;
}
//================================================================
LRESULT CSo7_TCPIP::OnSocket(WPARAM wParam, LPARAM lParam)
{
// 取得有事件发生的套节字句柄
SOCKET s = wParam;
// 查看是否出错
int errorCode = WSAGETSELECTERROR(lParam);
if(errorCode)
return errorCode; //should put a message up here
int event = WSAGETSELECTEVENT(lParam);
switch(event)
{
case FD_CONNECT:
{
}
break;
case FD_READ:
{
m_ProcessSocketReadEvent(s);
}
break;
case FD_WRITE:
//This event happens when the tcp buffers are ready for another send.
//So if there is not enough room for the first write the event will happen
//and then the buffers are ready for more.
m_ProcessSocketWriteEvent();
break;
case FD_CLOSE:
break;
}
return 0;
}
//================================================================
void CSo7_TCPIP::m_ClearSendBuf(void)
{
int i;
for(i=0;i<m_iSendMaxBufSize;i++)
{
m_TCPIPBuf[CH_SEND]._buffer[i] = 0x0;
}
m_TCPIPBuf[CH_SEND]._CompletedSize=0;
m_TCPIPBuf[CH_SEND]._size=0;
m_TCPIPBuf[CH_RECV]._CompletedSize=0;
m_TCPIPBuf[CH_RECV]._size=0;
}
//================================================================
void CSo7_TCPIP::SendBuffer()
{
int errorCode, numBytesSent;
bool bInfinite=true;
while(bInfinite)
{
numBytesSent = send(m_Socket, &(m_TCPIPBuf[CH_SEND]._buffer[m_TCPIPBuf[CH_SEND]._CompletedSize]), m_TCPIPBuf[CH_SEND]._size-m_TCPIPBuf[CH_SEND]._CompletedSize, 0);
if(numBytesSent == SOCKET_ERROR)
{
errorCode = WSAGetLastError();
if(errorCode == WSAEWOULDBLOCK)
{
m_TCPIPData.s_status._SendReturnCode=(TCPIP_RETURN_CODE)errorCode;
m_TCPIPBuf[CH_SEND]._hProtoPending=FALSE;
return; //Should get a FD_WRITE event if this happens. Send the rest from there.
}
m_TCPIPData.s_status._SendReturnCode=(TCPIP_RETURN_CODE)errorCode;
m_TCPIPBuf[CH_SEND]._hProtoPending=FALSE;
return; //should check for other errors here, and set an error code or something.
}
else
{
m_TCPIPBuf[CH_SEND]._CompletedSize += numBytesSent;
}
if(m_TCPIPBuf[CH_SEND]._CompletedSize>=m_TCPIPBuf[CH_SEND]._size)
{
m_TCPIPBuf[CH_SEND]._size = 0;
m_TCPIPBuf[CH_SEND]._CompletedSize = 0;
m_TCPIPBuf[CH_SEND]._hProtoPending=FALSE;
break;
}
}
}
//================================================================
void CSo7_TCPIP::m_ProcessSocketWriteEvent(void)
{
int errorCode, numBytesSent;
SOCKET s = m_Socket;
if(m_TCPIPBuf[CH_SEND]._size <= 0)
return;
char* sendBuf = m_TCPIPBuf[CH_SEND]._buffer;
while(1)
{
numBytesSent = send(s, &(sendBuf[m_TCPIPBuf[CH_SEND]._CompletedSize]), m_TCPIPBuf[CH_SEND]._size-m_TCPIPBuf[CH_SEND]._CompletedSize, 0);
if(numBytesSent == SOCKET_ERROR)
{
errorCode = WSAGetLastError();
m_TCPIPData.s_status._SendReturnCode=(TCPIP_RETURN_CODE)errorCode;
if(errorCode == WSAEWOULDBLOCK)
{
return; //Should get a FD_WRITE event if this happens. Send the rest from there.
}
else
{
//showSocketError(errorCode);
return;
}
}
else
{
m_TCPIPBuf[CH_SEND]._CompletedSize += numBytesSent;
}
if(m_TCPIPBuf[CH_SEND]._CompletedSize>=m_TCPIPBuf[CH_SEND]._size)
{
m_TCPIPBuf[CH_SEND]._CompletedSize = 0;
m_ClearSendBuf();
break;
}
}
}
//================================================================
void CSo7_TCPIP::m_ProcessSocketReadEvent(SOCKET s)
{
int bytesReceived=0;
int errorCode;
bytesReceived = recv(s, &(m_TCPIPBuf[CH_RECV]._buffer[0]), m_iReceiveMaxBufSize, 0);
if(bytesReceived == SOCKET_ERROR)
{
errorCode = WSAGetLastError();
m_TCPIPData.s_status._RecvReturnCode=(TCPIP_RETURN_CODE)errorCode;
if (errorCode == WSAEWOULDBLOCK)
{
//have to wait for the next receive event
return;
}
else
{
//showSocketError(errorCode);
return;
}
}
m_TCPIPBuf[CH_RECV]._CompletedSize += bytesReceived;
m_TCPIPBuf[CH_RECV]._size = m_TCPIPBuf[CH_RECV]._CompletedSize;
switch (m_TCPIPBuf[CH_SEND]._save_send_cmd)
{
case TCPIP_CMD_HANDSHAKING:
{
if (m_TCPIPBuf[CH_RECV]._CompletedSize==24)
{
m_TCPIPData.s_status._HandshakingSucceed=true;
}
else
{
m_TCPIPData.s_status._HandshakingSucceed=false;
}
break;
}
case TCPIP_CMD_READ_D_DATA:
{
int _BufferSize(0);
BYTE _bData[4]={0,0,0,0};
_bData[0]=static_cast<BYTE>(m_TCPIPBuf[CH_RECV]._buffer[DRW_RSDataIndexBufSize1]);
_bData[1]=static_cast<BYTE>(m_TCPIPBuf[CH_RECV]._buffer[DRW_RSDataIndexBufSize2]);
_BufferSize=static_cast<int>((_bData[0]<<8)+_bData[1]);
_BufferSize-=DRW_RDataCCLen;
m_TCPIPData.s_recv_data._DataSize=0;
for (int i=0;i<_BufferSize;i+=2)
{
_bData[0]=static_cast<BYTE>(m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexData+i]);
_bData[1]=static_cast<BYTE>(m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexData+i+1]);
//_bData[2]=static_cast<BYTE>(m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexData+i+2]);
//_bData[3]=static_cast<BYTE>(m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexData+i+3]);
_bData[2]=0;
_bData[3]=0;
m_TCPIPData.s_recv_data._lData[m_TCPIPData.s_recv_data._DataSize]=static_cast<int>(+(_bData[2]<<24)+(_bData[3]<<16)+(_bData[0]<<8)+(_bData[1]));
m_TCPIPData.s_recv_data._DataSize++;
}
m_TCPIPData.s_status._ReadDataCompleted=true;
break;
}
case TCPIP_CMD_WRITE_D_DATA:
{
m_TCPIPData.s_status._WriteDataCompleted=true;
break;
}
default:break;
}
m_TCPIPBuf[CH_RECV]._CompletedSize = 0;
m_TCPIPBuf[CH_RECV]._hProtoPending=FALSE;
::PostMessage(m_hMsgWnd,WM_TCPIP_RECV_DATA,m_TCPIPBuf[CH_SEND]._save_send_cmd,m_TCPIPData.s_status._RecvReturnCode);
}