Files
EF3-Interface/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.cpp
T
2014-10-29 21:05:58 +08:00

353 lines
9.0 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)
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;
u_short CSo7_TCPIP::m_iServerPortNumber=static_cast<u_short>(0);
//================================================================
CSo7_TCPIP::CSo7_TCPIP()
{
m_hMsgWnd=NULL;
m_ReceiveBuf=NULL;
m_SendBuf=NULL;
m_iBytesToReceive = 0;
m_iBytesReceived = 0;
m_iBytesToSend = 0;
m_iBytesSent = 0;
m_ReceiveBuf = new char[m_iReceiveMaxBufSize];
m_SendBuf = new char[m_iSendMaxBufSize];
}
//================================================================
CSo7_TCPIP::~CSo7_TCPIP()
{
DisConnect();
if(m_SendBuf)
delete [] m_SendBuf;
m_SendBuf=NULL;
if(m_ReceiveBuf)
delete [] m_ReceiveBuf;
m_ReceiveBuf=NULL;
}
//================================================================
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
{
// 设置socket为窗口通知消息类型
::WSAAsyncSelect(m_Socket, m_hMsgWnd,WM_SOCKET, FD_CONNECT | FD_CLOSE | FD_WRITE | FD_READ);
// 填写服务器地址信息
sockaddr_in remote;
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;
}
}
return rCode;
}
//================================================================
TCPIP_RETURN_CODE CSo7_TCPIP::DisConnect()
{
if(m_Socket == INVALID_SOCKET)
{
return TCPIP_INVAILD_SOCKET;
}
::closesocket(m_Socket);
m_Socket = INVALID_SOCKET;
return TCPIP_CONNECT_OK;
}
//================================================================
TCPIP_RETURN_CODE CSo7_TCPIP::GetHostIPAddr(in_addr& _IPAddress)
{
if(m_Socket == INVALID_SOCKET)
{
return TCPIP_INVAILD_SOCKET;
}
char HostName[100];
gethostname(HostName,sizeof(HostName));
hostent *pAddr;
pAddr=gethostbyname(HostName);
memcpy(&_IPAddress,pAddr->h_addr_list[0],sizeof(in_addr));
return TCPIP_CONNECT_OK;
}
//================================================================
TCPIP_RETURN_CODE CSo7_TCPIP::Send(int _Addr,int _Data)
{
_Addr=0;
_Data=0;
if(m_Socket == INVALID_SOCKET)
{
return TCPIP_INVAILD_SOCKET;
}
int i, errorCode, numBytesSent;
unsigned long numDataBytes;
SOCKET s = m_Socket;
m_iBytesSent = 0;
m_iBytesToSend = sizeof(unsigned long) + 1;
numDataBytes = htonl(m_iBytesToSend);
for(i=0;i<sizeof(unsigned long);i++)
m_SendBuf[i] = ((char*)(&numDataBytes))[i];
m_SendBuf[sizeof(unsigned long)] = 3;
//send the header
bool bInfinite=true;
while(bInfinite)
{
numBytesSent = send(s, &(m_SendBuf[m_iBytesSent]), m_iBytesToSend-m_iBytesSent, 0);
if(numBytesSent == SOCKET_ERROR)
{
errorCode = WSAGetLastError();
if(errorCode == WSAEWOULDBLOCK)
{
return (TCPIP_RETURN_CODE)errorCode; //Should get a FD_WRITE event if this happens. Send the rest from there.
}
return (TCPIP_RETURN_CODE)errorCode; //should check for other errors here, and set an error code or something.
}
else
{
m_iBytesSent += numBytesSent;
}
if(m_iBytesSent>=m_iBytesToSend)
{
m_iBytesToSend = 0;
m_iBytesSent = 0;
break;
}
}
return TCPIP_CONNECT_OK;
}
//================================================================
TCPIP_RETURN_CODE CSo7_TCPIP::Recv(int _Addr,int& _Data,bool _bWait)
{
_Addr=0;
_Data=0;
_bWait=false;
if(m_Socket == INVALID_SOCKET)
{
return TCPIP_INVAILD_SOCKET;
}
return TCPIP_CONNECT_OK;
}
//================================================================
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::clearSendBuf(void)
{
int i;
for(i=0;i<m_iSendMaxBufSize;i++)
{
m_SendBuf[i] = 0x0;
}
}
//================================================================
void CSo7_TCPIP::m_ProcessSocketWriteEvent(void)
{
int errorCode, numBytesSent;
SOCKET s = m_Socket;
if(m_iBytesToSend <= 0)
return;
char* sendBuf = m_SendBuf;
while(1)
{
numBytesSent = send(s, &(sendBuf[m_iBytesSent]), m_iBytesToSend-m_iBytesSent, 0);
if(numBytesSent == SOCKET_ERROR)
{
errorCode = WSAGetLastError();
if(errorCode == WSAEWOULDBLOCK)
{
return; //Should get a FD_WRITE event if this happens. Send the rest from there.
}
else
{
//showSocketError(errorCode);
return;
}
}
else
{
m_iBytesSent += numBytesSent;
}
if(m_iBytesSent>=m_iBytesToSend)
{
m_iBytesSent = 0;
clearSendBuf();
break;
}
}
}
//================================================================
void CSo7_TCPIP::m_ProcessSocketReadEvent(SOCKET s)
{
int bytesReceived=0;
int headerSize = sizeof(unsigned long) + sizeof(char);
int errorCode;
if(true)
{
unsigned long *numBytesPtr;
bytesReceived = recv(s, &(m_ReceiveBuf[m_iBytesReceived]), headerSize-m_iBytesReceived, 0);
if(bytesReceived == SOCKET_ERROR)
{
errorCode = WSAGetLastError();
if (errorCode == WSAEWOULDBLOCK)
{
//have to wait for the next receive event
return;
}
else
{
//showSocketError(errorCode);
return;
}
}
m_iBytesReceived += bytesReceived;
if(m_iBytesReceived < sizeof(unsigned long) + sizeof(char))
{//like this will ever happen... Have to wait for the next receive event
return;
}
numBytesPtr = (unsigned long*) &(m_ReceiveBuf[0]);
m_iBytesToReceive = ntohl(*numBytesPtr);
m_iBytesReceived = 0;
//allocate memory for the character or the double array
if(true)
{
if(m_dReceiveDBuf)
{//clean memory because returning
delete [] m_dReceiveDBuf;
m_dReceiveDBuf = NULL;
}
m_iReceiveDBufSize = m_iBytesToReceive/(sizeof(double));
m_dReceiveDBuf = new double[m_iReceiveDBufSize];
memset (m_dReceiveDBuf,m_iReceiveDBufSize*sizeof(double),0); // PR#254048
}
}
//The header has been received. Now we need to get the data
if(true)
{
bytesReceived = recv(s, &(((char*)m_dReceiveDBuf)[m_iBytesReceived]),
m_iBytesToReceive - m_iBytesReceived, 0);
}
if(bytesReceived == SOCKET_ERROR)
{
errorCode = WSAGetLastError();
if (errorCode == WSAEWOULDBLOCK)
{//have to wait for the next receive event
return;
}
else
{
if(m_dReceiveDBuf)
{//clean memory because returning
delete [] m_dReceiveDBuf;
m_dReceiveDBuf = NULL;
m_iReceiveDBufSize = 0;
}
//showSocketError(errorCode);
return;
}
}
m_iBytesReceived += bytesReceived;
if(m_iBytesReceived >= m_iBytesToReceive)
{
//we are done, reset the variables for next data and clean up
m_iBytesReceived = 0;
m_iBytesToReceive = 0;
if(m_dReceiveDBuf)
{
delete [] m_dReceiveDBuf;
m_dReceiveDBuf = NULL;
m_iReceiveDBufSize = 0;
}
}
}