// SocketEx.h: interface for the CSocketEx class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_SOCKETEX_H__78840EDA_D918_4017_A6AB_D3ADF120E9D8__INCLUDED_)
#define AFX_SOCKETEX_H__78840EDA_D918_4017_A6AB_D3ADF120E9D8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <atlbase.h>
#include <afxsock.h>
class CSocketEx
{
public:
CSocketEx()
{
m_hSocket = INVALID_SOCKET;
}
virtual ~CSocketEx(){}
SOCKET m_hSocket;
int m_nLastError;
void operator = (CSocketEx & Socket)
{
Detach();
Attach(Socket.m_hSocket);
}
BOOL Accept(CSocketEx & Socket)
{
// Socket should be valid.
if(m_hSocket == INVALID_SOCKET)
return false;
SOCKET hSocket = accept(m_hSocket,NULL,NULL);
if(hSocket == INVALID_SOCKET)
return false;
return Socket.Attach(hSocket);
}
BOOL Attach(SOCKET hSocket)
{
if(m_hSocket == INVALID_SOCKET)
{
m_hSocket = hSocket;
return true;
}
return false;
}
BOOL Connect(LPCTSTR lpszHost, int nPort)
{
SOCKADDR_IN sockAddr;
int bRet;
if(!TranslateRemoteAddress(lpszHost,nPort,sockAddr))
{
closesocket(m_hSocket);
m_hSocket = INVALID_SOCKET;
return false;
}
bRet = connect(m_hSocket,(SOCKADDR*)&sockAddr, sizeof(sockAddr));
if(bRet != 0)
{
m_nLastError = WSAGetLastError();
closesocket(m_hSocket);
m_hSocket = INVALID_SOCKET;
return false;
}
SetTimeout();
return true;
}
BOOL Create(int nPort, LPCTSTR lpszHost)
{
// Socket must be empty
if(m_hSocket != INVALID_SOCKET)
{
return false;
}
m_hSocket = socket(PF_INET,SOCK_STREAM,0);
if(m_hSocket != INVALID_SOCKET)
{
if(Bind(nPort,lpszHost))
{
if(nPort==0)
{
// To connect , set timeout only for 10 seconds
SetTimeout(10*1000);
}
return TRUE;
}
}
m_nLastError = WSAGetLastError();
Close();
return false;
}
void SetTimeout(int Timeout = 60*1000)
{
setsockopt(m_hSocket,IPPROTO_TCP,SO_RCVTIMEO,(char *)&Timeout,sizeof(Timeout));
setsockopt(m_hSocket,IPPROTO_TCP,SO_SNDTIMEO,(char *)&Timeout,sizeof(Timeout));
}
SOCKET Detach()
{
SOCKET hSocket = m_hSocket;
m_hSocket = INVALID_SOCKET;
return hSocket;
}
BOOL Disconnect()
{
if(m_hSocket != INVALID_SOCKET)
{
if(shutdown(m_hSocket,2) == SOCKET_ERROR)
return false;
return Close();
}
return true;
}
BOOL GetPeerName(CString & sPeerAddress, int & nPeerPort)
{
// Socket should be valid.
if(m_hSocket == INVALID_SOCKET)
return false;
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
BOOL bResult = (getpeername(m_hSocket,(SOCKADDR*)&sockAddr, &nSockAddrLen) != SOCKET_ERROR);
if (bResult)
{
nPeerPort = ntohs(sockAddr.sin_port);
sPeerAddress = inet_ntoa(sockAddr.sin_addr);
}
return bResult;
}
CString GetLastError()
{
CString strError;
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
m_nLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
strError += CString((LPCTSTR)lpMsgBuf);
LocalFree( lpMsgBuf );
return strError;
}
BOOL Listen()
{
// Socket should be valid.
if(m_hSocket == INVALID_SOCKET)
{
return false;
}
return (listen(m_hSocket,SOMAXCONN) != SOCKET_ERROR);
}
BOOL Close()
{
SOCKET hSocket = m_hSocket;
m_hSocket = INVALID_SOCKET;
if(m_hSocket != INVALID_SOCKET)
{
return (closesocket(hSocket) != SOCKET_ERROR);
}
return true;
}
int Receive(LPVOID lpBuffer, int nSize)
{
if(m_hSocket == INVALID_SOCKET)
{
return -1;
}
int n = recv(m_hSocket,(char *)lpBuffer,nSize,0);
m_nLastError = WSAGetLastError();
return n==SOCKET_ERROR ? -1 : n;
}
int Send(LPVOID lpBuffer, int nSize)
{
if(m_hSocket == INVALID_SOCKET)
{
SOCKET_ERROR;
}
int nSent = send(m_hSocket,(char *)lpBuffer,nSize,0);
if(nSent == SOCKET_ERROR)
{
m_nLastError = WSAGetLastError();
return SOCKET_ERROR;
}
return nSent;
}
void SetProxySettings(int nVersion, LPCTSTR lpszProxyHost, int nProxyPort, LPCTSTR lpszUsername, LPCTSTR lpszPassword)
{
}
BOOL Shutdown(int nMethod)
{
if(m_hSocket != INVALID_SOCKET)
{
return(shutdown(m_hSocket,nMethod)!= SOCKET_ERROR);
}
return true;
}
BOOL TranslateAddress(LPCTSTR lpszHost, int nPort, SOCKADDR_IN &sockAddr)
{
USES_CONVERSION;
memset(&sockAddr,0,sizeof(sockAddr));
LPSTR lpszAscii = T2A((LPTSTR)lpszHost);
sockAddr.sin_family = AF_INET;
if (lpszHost == NULL)
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
else
{
DWORD lResult = inet_addr(lpszHost);
if (lResult == INADDR_NONE)
{
WSASetLastError(WSAEINVAL);
return FALSE;
}
sockAddr.sin_addr.s_addr = lResult;
}
sockAddr.sin_port = htons((u_short)nPort);
return true;
}
BOOL GetSocketName(CString &sAddress, int &nPort)
{
// Socket should be valid.
if(m_hSocket == INVALID_SOCKET)
return false;
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
BOOL bResult = (getsockname(m_hSocket,(SOCKADDR*)&sockAddr, &nSockAddrLen) != SOCKET_ERROR);
if (bResult)
{
nPort = ntohs(sockAddr.sin_port);
sAddress = inet_ntoa(sockAddr.sin_addr);
}
return bResult;
}
BOOL ReadLine(CString &String)
{
// Socket should be valid.
if(m_hSocket == INVALID_SOCKET)
{
return false;
}
char ch;
String.Empty();
do
{
int n = recv(m_hSocket,&ch,1,0);
if(n == SOCKET_ERROR || n==0)
{
Close();
m_hSocket = INVALID_SOCKET;
return false;
}
if(ch == '\n')
{
if(String.GetLength()>=1)
{
if(String[String.GetLength()-1]=='\r')
{
String = String.Left(String.GetLength()-1);
return true;
}
}
}
String += ch;
}while(true);
return true;
}
BOOL TranslateRemoteAddress(LPCTSTR lpszHost, int nPort, SOCKADDR_IN &sockAddr)
{
USES_CONVERSION;
ASSERT(lpszHost != NULL);
memset(&sockAddr,0,sizeof(sockAddr));
LPSTR lpszAscii = T2A((LPTSTR)lpszHost);
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
{
LPHOSTENT lphost;
lphost = gethostbyname(lpszAscii);
if (lphost != NULL)
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
{
WSASetLastError(WSAEINVAL);
return FALSE;
}
}
sockAddr.sin_port = htons((u_short)nPort);
return true;
}
BOOL Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress)
{
USES_CONVERSION;
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
LPSTR lpszAscii = T2A((LPTSTR)lpszSocketAddress);
sockAddr.sin_family = AF_INET;
if (lpszAscii == NULL)
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
else
{
DWORD lResult = inet_addr(lpszAscii);
if (lResult == INADDR_NONE)
{
WSASetLastError(WSAEINVAL);
return FALSE;
}
sockAddr.sin_addr.s_addr = lResult;
}
sockAddr.sin_port = htons((u_short)nSocketPort);
return (bind(m_hSocket,(SOCKADDR*)&sockAddr, sizeof(sockAddr)) != SOCKET_ERROR);
}
};
#endif // !defined(AFX_SOCKETEX_H__78840EDA_D918_4017_A6AB_D3ADF120E9D8__INCLUDED_)