#include "StdAfx.h" #include #include #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(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;iSendBuffer(); 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(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_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(m_TCPIPBuf[CH_RECV]._buffer[DRW_RSDataIndexBufSize1]); _bData[1]=static_cast(m_TCPIPBuf[CH_RECV]._buffer[DRW_RSDataIndexBufSize2]); _BufferSize=static_cast((_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(m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexData+i]); _bData[1]=static_cast(m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexData+i+1]); //_bData[2]=static_cast(m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexData+i+2]); //_bData[3]=static_cast(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(+(_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); }