353 lines
9.0 KiB
C++
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;
|
|
}
|
|
}
|
|
}
|