Click here to Skip to main content
12,243,180 members (20,191 online)
Click here to Skip to main content

Stats

143.5K views
6K downloads
59 bookmarked
Posted

Use of free SocketPro package for creating super client and server applications

, 23 Feb 2002
A set of socket libraries for writing distributed computing applications over the internet
netdemo
ClientComponents
MultiSvsSample
SvrComponents
bin
include
lib
Samples
client
DnsSvs
GetHTML
InternetIO
MultiSvsSample
SpeedTest
res
DResolver
Svr
NormalApp
NTSvs
help
trash
SecureSocket
SafeSocket
DNSResolver.exe
GetHtml.exe
IONet.exe
MultipleSvs.exe
MultiSvs.exe
MultiSvsClient.exe
NetBaseR.dll
SafeSocket.exe
SecureSocket.exe
SpeedTest.exe
ClientSocket.dll
DResolver.dll
SBroker.dll
SockFile.dll
fundamental.gif
patterns.gif
NetBaseR.lib
DNSResolver
DNSResolver.vbp
DNSResolver.vbw
frmDNSResolver.frm
frmDNSResolver.frx
frmChatClient.frm
frmChatClient.frx
GETHTML.vbp
GETHTML.vbw
iIO.frm
IONet
IONet.vbp
IONet.vbw
frmMultiSvs.frm
frmMultiSvs.frx
MultiSvs.vbp
MultiSvs.vbw
SafeSocket.vbp
SafeSocket.vbw
SecureSocket.frm
SpeedTest.ico
SpeedTest.aps
SpeedTest.clw
SpeedTest.dsp
SpeedTest.dsw
dlldata.obj
DNS.rgs
DResolver.aps
DResolver.def
DResolver.dsp
DResolver.dsw
DResolver.opt
DResolver.plg
DResolver.tlb
DResolverps.def
DResolverps.exp
DResolverps.lib
DResolverps.mk
DResolver_i.obj
DResolver_p.obj
MultipleSvs.dsp
MultipleSvs.dsw
MultiSvs.dsp
MultiSvs.dsw
MultiSvs.rgs
MultiSvs.tlb
MultiSvsps.def
MultiSvsps.mk
dlldata.obj
SafeSocket.aps
SafeSocket.dsp
SafeSocket.dsw
SafeSocket.plg
SafeSocket.rgs
SafeSocket.tlb
SafeSocketps.def
SafeSocketps.dll
SafeSocketps.exp
SafeSocketps.lib
SafeSocketps.mk
SafeSocket_i.obj
SafeSocket_p.obj
SPassword.rgs
MultipleSvs.exe
MultiSvs.exe
NetBaseR.dll
SafeSocket.exe
// DNS.cpp : Implementation of CDNS
#include "stdafx.h"
#include "DResolver.h"
#include "DNS.h"
#include "ClientSocket_i.c"
#include "ClientInfo.h"
#include <stdio.h>

//hard coded, see the defines in the file ..\extending\server\hostdnssvs.h
//#define HOST_DNS_SVS_SOCKET		0xA00100DD
/*typedef enum tagDResolverID
	{
		idGetDNSByName=			1,
		idGetDNSByAddr=			2,
		idGetCountClients	=	3,
		idGetClients =			4,
	}DResolverID;*/
/////////////////////////////////////////////////////////////////////////////
// CDNS

HRESULT	CDNS::RecvChunk(void *pBuffer, long *plRecv)
{
	CComPtr<ISktClient> pISktClient;
	HRESULT	hr=S_OK;
	VARIANT	vtData;
	VariantInit(&vtData);
	do
	{
		void	*pData;
		hr=m_pIUnknown.QueryInterface(&pISktClient);
		if(FAILED(hr))
			break;
		hr=pISktClient->RecvChunk(plRecv, 0, &vtData);
		if(FAILED(hr))
			break;
		SAFEARRAY	*psa=vtData.parray;
		hr=SafeArrayAccessData(psa, &pData);
		if(FAILED(hr))
			break;
		memcpy(pBuffer, pData, *plRecv);
		SafeArrayUnaccessData(psa);
	}while(false);
	VariantClear(&vtData);
	if(!FAILED(hr))
		hr=S_OK;
	return hr;
}

HRESULT	CDNS::SendChunk(void *pBuffer, long nSize, long *plSent)
{
	CComPtr<ISktClient> pISktClient;
	HRESULT	hr=S_OK;
	VARIANT	vtData;
	VariantInit(&vtData);
	do
	{
		void	*pData;
		hr=m_pIUnknown.QueryInterface(&pISktClient);
		if(FAILED(hr))
			break;
		SAFEARRAYBOUND	bound;
		bound.cElements=nSize;
		bound.lLbound=0;
		vtData.vt=VT_ARRAY|VT_UI1;
		SAFEARRAY	*psa=SafeArrayCreate(VT_UI1, 1, &bound);
		hr=SafeArrayAccessData(psa, &pData);
		if(FAILED(hr))
			break;
		memcpy(pData, pBuffer, nSize);
		SafeArrayUnaccessData(psa);
		vtData.parray=psa;
		hr=pISktClient->SendChunk(vtData, 0, plSent);
	}while(false);
	VariantClear(&vtData);
	if(!FAILED(hr))
		hr=S_OK;
	return hr;
}

STDMETHODIMP CDNS::GetClients()
{
	CStreamHeader	StreamHeader;
	BYTE *pBuffer=NULL;
	StreamHeader.m_nValue=idGetClients;
	CComPtr<ISktClient> pISktClient;
	Lock();
	do
	{
		long	lSent=0;
		long	lEvents;
		m_hrDNS=SendChunk(&StreamHeader, sizeof(StreamHeader), &lSent);
		if(FAILED(m_hrDNS))
			break;
		m_hrDNS=m_pIUnknown.QueryInterface(&pISktClient);
		if(FAILED(m_hrDNS))
			break;
		pISktClient->get_Events(&lEvents);
		if((lEvents & FD_READ) != FD_READ)	//if blocking mode used
		{
			UINT nCount;
			long lRecv=sizeof(StreamHeader);
			m_hrDNS=RecvChunk(&StreamHeader, &lRecv);
			if(FAILED(m_hrDNS))
				break;
			if(FAILED(StreamHeader.m_nValue))
				break;
			pBuffer=new BYTE[StreamHeader.m_nLen];
			lRecv=StreamHeader.m_nLen;
			m_hrDNS=RecvChunk(pBuffer, &lRecv);
			if(FAILED(m_hrDNS))
				break;
			if(m_bstrClients)
			{
				::SysFreeString(m_bstrClients);
				m_bstrClients=NULL;
			}
			ATLASSERT((lRecv%sizeof(CClientInfo))==0);
			nCount=lRecv/sizeof(CClientInfo);
			if(nCount)
			{
				CComBSTR	bstrClients;
				for(UINT n=0; n<nCount; n++)
				{
					BYTE	*p=pBuffer+n*sizeof(CClientInfo);
					CClientInfo* pInfo=(CClientInfo*)p;
					{
						char	strTemp[50]={0};
						unsigned short nPort=pInfo->m_nPort;
						if(n)
							sprintf(strTemp, ",%s:%d", inet_ntoa(*((in_addr*)&(pInfo->m_nIPAddr))), nPort);
						else
							sprintf(strTemp, "%s:%d", inet_ntoa(*((in_addr*)&(pInfo->m_nIPAddr))), nPort);
						bstrClients +=CComBSTR(strTemp);
					}
				}
				m_bstrClients=bstrClients.m_str;
				bstrClients.m_str=NULL;
			}
		}
	}while(false);
	if(pBuffer)
		delete []pBuffer;
	Unlock();
	return m_hrDNS;
}

STDMETHODIMP CDNS::GetCountClients()
{
	CStreamHeader	StreamHeader;
	StreamHeader.m_nValue=idGetCountClients;
	CComPtr<ISktClient> pISktClient;
	Lock();
	do
	{
		long	lSent=0;
		long	lEvents=0;
		m_hrDNS=SendChunk(&StreamHeader, sizeof(StreamHeader), &lSent);
		if(FAILED(m_hrDNS))
			break;
		m_hrDNS=m_pIUnknown.QueryInterface(&pISktClient);
		if(FAILED(m_hrDNS))
			break;
		pISktClient->get_Events(&lEvents);
		if((lEvents & FD_READ) != FD_READ)	//if blocking mode used
		{
			USES_CONVERSION;
			long lRecv=sizeof(StreamHeader);
			m_hrDNS=RecvChunk(&StreamHeader, &lRecv);
			if(FAILED(m_hrDNS))
				break;
			if(FAILED(StreamHeader.m_nValue))
				break;
			ATLASSERT(StreamHeader.m_nLen==sizeof(m_lCount));
			lRecv=sizeof(m_lCount);
			m_hrDNS=RecvChunk(&m_lCount, &lRecv);
			if(FAILED(m_hrDNS))
				break;
		}
	}while(false);
	Unlock();
	return m_hrDNS;
}

STDMETHODIMP CDNS::GetDnsByName(BSTR bstrName)
{
	CStreamHeader	StreamHeader;
	StreamHeader.m_nValue=idGetDNSByName;
	CComPtr<ISktClient> pISktClient;
	Lock();
	m_hrDNS=S_OK;
	do
	{
		USES_CONVERSION;
		long nLen=0;
		long	lEvents=0;
		CPacking	Packing;
		if(!bstrName|| (nLen=::SysStringLen(bstrName))==0)
		{
			m_hrDNS=E_UNEXPECTED;
			break;
		}
		StreamHeader.m_nLen=nLen;

		Packing.Pack(&StreamHeader, sizeof(StreamHeader));
		Packing.Pack(OLE2A(bstrName), nLen);
		m_hrDNS=SendChunk(Packing.m_pBuffer, Packing.m_nLen, &nLen);
		if(FAILED(m_hrDNS))
			break;
		m_hrDNS=m_pIUnknown.QueryInterface(&pISktClient);
		if(FAILED(m_hrDNS))
			break;

		pISktClient->get_Events(&lEvents);
		if((lEvents & FD_READ) != FD_READ)	//if blocking mode used, we need to process it now
		{
			USES_CONVERSION;
			long lRecv=sizeof(StreamHeader);
			m_hrDNS=RecvChunk(&StreamHeader, &lRecv);
			if(FAILED(m_hrDNS))
				break;
			if(FAILED(StreamHeader.m_nValue))
			{
				m_hrDNS=StreamHeader.m_nValue;
				break;
			}
			if(m_bstrHostEnt)
			{
				::SysFreeString(m_bstrHostEnt);
				m_bstrHostEnt=NULL;
			}
			lRecv=StreamHeader.m_nLen;
			if(lRecv)
			{
				char *strBuffer=new char[lRecv+1];
				m_hrDNS=RecvChunk(strBuffer, &lRecv);
				if(FAILED(m_hrDNS))
				{
					delete []strBuffer;
					break;
				}
				strBuffer[lRecv]=0;
				m_bstrHostEnt=A2BSTR(strBuffer);
				delete []strBuffer;
			}
		}
	}while(false);
	Unlock();
	return m_hrDNS;
}

STDMETHODIMP CDNS::GetDnsByAddr(BSTR bstrAddr)
{
	CStreamHeader	StreamHeader;
	StreamHeader.m_nValue=idGetDNSByAddr;
	CComPtr<ISktClient> pISktClient;
	Lock();
	m_hrDNS=S_OK;
	do
	{
		USES_CONVERSION;
		long nLen=0;
		long	lEvents=0;
		CPacking	Packing;
		if(!bstrAddr|| (nLen=::SysStringLen(bstrAddr))==0)
		{
			m_hrDNS=E_UNEXPECTED;
			break;
		}
		StreamHeader.m_nLen=nLen;

		Packing.Pack(&StreamHeader, sizeof(StreamHeader));
		Packing.Pack(OLE2A(bstrAddr), nLen);
		m_hrDNS=SendChunk(Packing.m_pBuffer, Packing.m_nLen, &nLen);
		if(FAILED(m_hrDNS))
			break;
		m_hrDNS=m_pIUnknown.QueryInterface(&pISktClient);
		if(FAILED(m_hrDNS))
			break;

		pISktClient->get_Events(&lEvents);
		if((lEvents & FD_READ) != FD_READ)	//if blocking mode used, we need to process it now
		{
			USES_CONVERSION;
			long lRecv=sizeof(StreamHeader);
			m_hrDNS=RecvChunk(&StreamHeader, &lRecv);
			if(FAILED(m_hrDNS))
				break;
			if(FAILED(StreamHeader.m_nValue))
			{
				m_hrDNS=StreamHeader.m_nValue;
				break;
			}
			if(m_bstrHostEnt)
			{
				::SysFreeString(m_bstrHostEnt);
				m_bstrHostEnt=NULL;
			}
			lRecv=StreamHeader.m_nLen;
			if(lRecv)
			{
				char *strBuffer=new char[lRecv+1];
				m_hrDNS=RecvChunk(strBuffer, &lRecv);
				if(FAILED(m_hrDNS))
				{
					delete []strBuffer;
					break;
				}
				strBuffer[lRecv]=0;
				m_bstrHostEnt=A2BSTR(strBuffer);
				delete []strBuffer;
			}
		}
	}while(false);
	Unlock();
	return m_hrDNS;
}

STDMETHODIMP CDNS::GetHostEnt(BSTR *pbstrHostEnt)
{
	Lock();
	if(!pbstrHostEnt)
	{
		m_hrDNS=E_UNEXPECTED;
		Unlock();
		return m_hrDNS;
	}
	m_hrDNS=S_OK;
	if(m_bstrHostEnt)
		*pbstrHostEnt=::SysAllocString(m_bstrHostEnt);
	Unlock();
	return S_OK;
}

STDMETHODIMP CDNS::Clients(BSTR *pbstrClients)
{
	Lock();
	if(!pbstrClients)
	{
		m_hrDNS=E_UNEXPECTED;
		Unlock();
		return m_hrDNS;
	}
	m_hrDNS=S_OK;
	if(m_bstrClients)
		*pbstrClients=::SysAllocString(m_bstrClients);
	Unlock();
	return S_OK;
}

STDMETHODIMP CDNS::Count(long *plCount)
{
	Lock();
	if(!plCount)
	{
		m_hrDNS=E_UNEXPECTED;
		Unlock();
		return m_hrDNS;
	}
	m_hrDNS=S_OK;
	*plCount=m_lCount;
	Unlock();
	return S_OK;
}

STDMETHODIMP CDNS::AttachSocket(IUnknown *pIUnknown)
{
	CComPtr<ISktClient>		pISktClient;
	CComPtr<IDResolver>		pIDResolver;
	VARIANT_BOOL			bIsConnected;
	VARIANT_BOOL			bDNSClient;
	long	hSocket=INVALID_SOCKET;
	long	hWnd=NULL;
	Lock();
	if(!pIUnknown)
	{
		m_hrDNS=E_UNEXPECTED;
		Unlock();
		return E_UNEXPECTED;
	}
	pIUnknown->QueryInterface(__uuidof(ISktClient), (void**)&pISktClient);
	if(!pISktClient.p)
	{
		m_hrDNS=E_UNEXPECTED;
		Unlock();
		return E_UNEXPECTED;
	}
	m_hrDNS=pIUnknown->QueryInterface(&pIDResolver);
	if(!FAILED(m_hrDNS))
	{
		bDNSClient=VARIANT_TRUE;
		CComPtr<IUnknown> pIUnknown;
		QueryInterface(__uuidof(IUnknown), (void**)&pIUnknown);
		if(pIUnknown.p && pIUnknown.IsEqualObject(pIUnknown))
		{
			m_hrDNS=E_UNEXPECTED;
			Unlock();
			return E_UNEXPECTED;
		}
	}
	else
		bDNSClient=VARIANT_FALSE;
	m_hrDNS=m_ClientSocketEvent.DispEventUnadvise(m_pIUnknown.p);
	if(m_pIUnknown.p)
		m_pIUnknown.Release();
	m_pIUnknown.p=pIUnknown;
	pIUnknown->AddRef();
	m_pIUnknownClientSocket=m_pIUnknown.p;
	m_pIUnknownForPointContainer=m_pIUnknown.p;
	m_hrDNS=m_ClientSocketEvent.DispEventAdvise(m_pIUnknown.p);
	if(FAILED(m_hrDNS))
	{
		Unlock();
		return m_hrDNS;
	}
	pISktClient->get_WinHandle(&hWnd);
	m_hWnd=hWnd;
	pISktClient->get_SocketHandle(&m_hSocket);
	if(bDNSClient==VARIANT_FALSE)
	{
		if(pISktClient->get_IsConnected(&bIsConnected)==S_OK && bIsConnected)
		{
			//SwitchTo call is blocking one
			m_hrDNS=pISktClient->SwitchTo(CREATE_START_SOCK_CLIENT);
			m_hrDNS=pISktClient->SwitchTo(0xA00100DDL);
		}
	}
	Unlock();
	return m_hrDNS;
}

HRESULT __stdcall CDNS::OnGetHostByAddr(LONG nHandle, BSTR bstrHostName, BSTR bstrHostAlias, LONG lError)
{
	return Fire_OnGetHostByAddr(nHandle, bstrHostName, bstrHostAlias, lError);
}

HRESULT __stdcall CDNS::OnGetHostByName(LONG hHandle, BSTR bstrHostName, BSTR bstrAlias, BSTR bstrIPAddr, LONG lError)
{
	return Fire_OnGetHostByName(hHandle, bstrHostName, bstrAlias, bstrIPAddr, lError);
}

HRESULT __stdcall CDNS::OnDataAvailable(long hSocket, long lBytes, long lError)
{
	CStreamHeader	StreamHeader;
aa:	if(lBytes>=sizeof(StreamHeader))
	{
		Lock();
		do
		{
			long lRecv=sizeof(StreamHeader);
			m_hrDNS=RecvChunk(&StreamHeader, &lRecv);
			lBytes -=lRecv;
			m_hrDNS=lError=StreamHeader.m_nValue;
			if(FAILED(m_hrDNS))
				break;
			if(StreamHeader.m_nLen)
			{
				USES_CONVERSION;
				lRecv=StreamHeader.m_nLen;
				switch (lError)
				{
				case idGetDNSByAddr:
				case idGetDNSByName:
					{
						char *str=new char [lRecv+1];
						m_hrDNS=RecvChunk(str, &lRecv);
						ATLASSERT(lRecv);
						str[lRecv]=0;
						if(m_bstrHostEnt)
							::SysFreeString(m_bstrHostEnt);
						m_bstrHostEnt=A2BSTR(str);
						delete []str;
					}
					break;
				case idGetCountClients:
					ATLASSERT(StreamHeader.m_nLen=sizeof(m_lCount));
					m_hrDNS=RecvChunk(&m_lCount, &lRecv);
					break;
				case idGetClients:
					{
						UINT nCount;
						BYTE *pBuffer=new BYTE[lRecv];
						m_hrDNS=RecvChunk(pBuffer, &lRecv);
						if(FAILED(m_hrDNS))
							break;
						ATLASSERT((lRecv%sizeof(CClientInfo))==0);
						nCount=lRecv/sizeof(CClientInfo);
						if(nCount)
						{
							CComBSTR	bstrClients;
							for(UINT n=0; n<nCount; n++)
							{
								BYTE	*p=pBuffer+n*sizeof(CClientInfo);
								CClientInfo* pInfo=(CClientInfo*)p;
								{
									char	strTemp[50]={0};
									unsigned short nPort=pInfo->m_nPort;
									if(n)
										sprintf(strTemp, ",%s:%d", inet_ntoa(*((in_addr*)&(pInfo->m_nIPAddr))), nPort);
									else
										sprintf(strTemp, "%s:%d", inet_ntoa(*((in_addr*)&(pInfo->m_nIPAddr))), nPort);
									bstrClients +=CComBSTR(strTemp);
								}
							}
							m_bstrClients=bstrClients.m_str;
							bstrClients.m_str=NULL;
						}
					}
					break;
				default:
					Unlock();
					return S_OK;
					break;
				}
				lBytes -=StreamHeader.m_nLen;
			}
		}while(false);
		Unlock();
		Fire_OnDataAvailable(hSocket, lBytes, lError);
	}
	if(lBytes>0 && lBytes>sizeof(StreamHeader))
	{
		goto aa; 
//		::PostMessage((HWND)m_hWnd, WM_SOCKET_CLIENT_NOTIFY, m_hSocket, FD_READ); //smoother but slight slower
	}
	return S_OK;
}

HRESULT __stdcall CDNS::OnSendingData(long hSocket, long lError)
{
	return Fire_OnSendingData(hSocket, lError);	
}

HRESULT __stdcall CDNS::OnSocketConnected(long hSocket, long lError)
{
	if(lError==S_OK)
	{
		CComPtr<ISktClient> pISktClient;
		Lock();
		m_hrDNS=m_pIUnknown.QueryInterface(&pISktClient);
		if(!FAILED(m_hrDNS))
			m_hrDNS=pISktClient->SwitchTo(g_nDResolverClassID);
		Unlock();
		ATLTRACE(_T("The client socket %d is connected with a host\n"), hSocket);
	}
	return Fire_OnSocketConnected(hSocket, lError);
}

HRESULT __stdcall CDNS::OnConnecting(long hSocket, long hWnd)
{
	ATLTRACE(_T("The client socket %d is connecting to a host......\n"), hSocket);
	m_hWnd=hWnd;
	m_hSocket=hSocket;
	return Fire_OnConnecting(hSocket, hWnd);
}

HRESULT __stdcall CDNS::OnSocketClosed(long hSocket, long lError)
{
	ATLTRACE(_T("The connected host is shut down\n"));
	return Fire_OnSocketClosed(hSocket, lError);
}

HRESULT __stdcall CDNS::OnOtherMessages(long nMsg, long wParam, long lParam)
{
	return Fire_OnOtherMessages(nMsg, wParam, lParam);
}

STDMETHODIMP CDNS::GetRtn(long *plResult)
{
	Lock();
	if(plResult)
	{
		if(m_hrDNS!=S_OK)
			*plResult=m_hrDNS;
		else
		{
			CComPtr<ISktClient> pISktClient;
			m_pIUnknown.QueryInterface(&pISktClient);
			pISktClient->GetRtn(plResult);
		}
	}
	Unlock();
	return S_OK;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Yuancai (Charlie) Ye
Web Developer
United States United States
Yuancai (Charlie) Ye, an experienced software engineer, lives in Atlanta, Georgia. He is an expert at OLEDB consumer and created a powerful data accessing libarary at the site http://www.udaparts.com. He has been working at SocketPro written from batching, asynchrony and parallel computation for more than three years. Visual C++, C# and ASP.NET are his favorite development environments.

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160426.1 | Last Updated 24 Feb 2002
Article Copyright 2002 by Yuancai (Charlie) Ye
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid