#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) 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(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=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_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; } } }