Advertisement

DirectPlay8 Client/Server

Started by April 11, 2002 07:14 AM
6 comments, last by Eibwen 22 years, 9 months ago
to learn directplay i try to code a simple chat... Server runs fine and waits for connections. But I have a problem with my client. If i call the DirectPlay8Client->Connect it returns "invalid argument". I think the problem is because i set the local DeviceAddress to NULL because i dont want to use lobbies. Is there a easy way to connect to a DirectPlay Server with only its hostname and port? How can i init the DeviceAddress correctly? I tried just to AddComponent TCP/IP Provider. And 127.0.0.1 as hostname but still no success. Any suggestions? Thanks
Here''s my server and client host and connect methods. Ignore the strange looking TRY / CATCH stuff, I was prototyping some custom exception handling. The encryption stuff is pretty straight forward, but ignore it as it''s not needed.


DxServer.cpp

  HRESULT CDxServer::Host(GUID guidApp, LPCTSTR lpSession, DWORD dwPort, bool bEncryption){	TRY;	HRESULT hr;	PDIRECTPLAY8ADDRESS pDpAddrLocal = NULL;	SAFE_RELEASE(m_pDpSrv);	WCHAR wstrSessionName[MAX_PATH];	DXUtil_ConvertGenericStringToWide(wstrSessionName, lpSession);    // Create IDirectPlay8Server	if(FAILED(hr = CoCreateInstance(CLSID_DirectPlay8Server, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlay8Server, (LPVOID*)&m_pDpSrv)))		THROW(hr, SEV_ERROR);	// Init IDirectPlay8Server	if(FAILED( hr = m_pDpSrv->Initialize(this, DPMsgHandler, 0)))		THROW(hr, SEV_ERROR);	if(FAILED(hr = CoCreateInstance(CLSID_DirectPlay8Address, NULL, CLSCTX_ALL, IID_IDirectPlay8Address, (LPVOID*) &pDpAddrLocal)))		THROW(hr, SEV_ERROR);    if(FAILED(hr = pDpAddrLocal->SetSP(&CLSID_DP8SP_TCPIP)))		THROW(hr, SEV_ERROR);	if(dwPort != 0)	{		if(FAILED(hr = pDpAddrLocal->AddComponent(DPNA_KEY_PORT, &dwPort, sizeof(dwPort), DPNA_DATATYPE_DWORD)))			THROW(hr, SEV_ERROR);	}	DPN_APPLICATION_DESC dpnAppDesc;	ZeroMemory( &dpnAppDesc, sizeof(DPN_APPLICATION_DESC) );	dpnAppDesc.dwSize           = sizeof( DPN_APPLICATION_DESC );	dpnAppDesc.dwFlags          = DPNSESSION_CLIENT_SERVER;	dpnAppDesc.guidApplication  = guidApp;	dpnAppDesc.pwszSessionName  = wstrSessionName;	if(FAILED(hr = m_pDpSrv->Host(&dpnAppDesc, &pDpAddrLocal, 1, NULL, NULL, NULL, 0)))		THROW(hr, SEV_ERROR);	OnHost();	CATCH;	ENDCATCH;    SAFE_RELEASE(pDpAddrLocal);    return hr;}  



DxClient.cpp

  HRESULT CDxClient::Connect(GUID guidApp, LPCTSTR lpHost, DWORD dwPort, bool bEncryption){	TRY;    DPN_APPLICATION_DESC        dpnAppDesc;	PDIRECTPLAY8ADDRESS pDpAddrHost = NULL;	HRESULT hr;	SAFE_RELEASE(m_pDpCli);	m_lpHost = lpHost;    WCHAR wstrHost[MAX_PATH];    DXUtil_ConvertGenericStringToWide(wstrHost, lpHost);    // Create IDirectPlay8Client    if(FAILED(hr = CoCreateInstance(CLSID_DirectPlay8Client, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlay8Client, (LPVOID*)&m_pDpCli)))		THROW(hr, SEV_ERROR);    // Init IDirectPlay8Client    if(FAILED(hr = m_pDpCli->Initialize(this, DPMsgHandler, 0)))		THROW(hr, SEV_ERROR);//        return DXTRACE_ERR( _T("Initialize"), hr );	if(FAILED(hr = CoCreateInstance(CLSID_DirectPlay8Address, NULL, CLSCTX_ALL, IID_IDirectPlay8Address, (LPVOID*) &pDpAddrHost)))		THROW(hr, SEV_ERROR);	if(FAILED(hr = pDpAddrHost->SetSP(&CLSID_DP8SP_TCPIP)))		THROW(hr, SEV_ERROR);	if(FAILED(hr = pDpAddrHost->AddComponent(DPNA_KEY_HOSTNAME, wstrHost, 2*(wcslen(wstrHost) + 1), DPNA_DATATYPE_STRING)))		THROW(hr, SEV_ERROR);	if(FAILED(hr = pDpAddrHost->AddComponent(DPNA_KEY_PORT, &dwPort, sizeof(dwPort), DPNA_DATATYPE_DWORD)))		THROW(hr, SEV_ERROR);    ZeroMemory(&dpnAppDesc, sizeof(DPN_APPLICATION_DESC));    dpnAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC);    dpnAppDesc.guidApplication = guidApp;	if(FAILED(hr = m_pDpCli->Connect(&dpnAppDesc, pDpAddrHost, NULL, NULL, NULL, pbKeyExchBlob, dwKeyExchBlob, NULL, NULL, DPNCONNECT_SYNC)))		THROW(hr, SEV_ERROR);	OnConnect();	CATCH;	ENDCATCH;	SAFE_RELEASE(pDpAddrHost);    return hr;}  
Advertisement
hi jonstelly,

how come there''s two AddComponent() on your client.cpp, dx automatically sets the port right?

anyway, am using peer to peer, and am wondering, while i''m connection to the host, my program doesn''t connect when i remove the EnumHost() function after successfully using the AddComponent()?
http://www.dualforcesolutions.comProfessional website designs and development, customized business systems, etc.,
oh and one more thing? in your dxServer.cpp, though i really haven''t tried client/server, why do you have to use AddComponent() prior to the Host() function? thanks,
http://www.dualforcesolutions.comProfessional website designs and development, customized business systems, etc.,
Mickey:

quote:
how come there''s two AddComponent() on your client.cpp, dx automatically sets the port right?


Yes that''s true, but if you want to hardcode the port you can use that component and you also don''t need enumhost if you specify the port.

quote:
anyway, am using peer to peer, and am wondering, while i''m connection to the host, my program doesn''t connect when i remove the EnumHost() function after successfully using the AddComponent()?


Specify the ports and then you don''t need EnumHost().

quote:
oh and one more thing? in your dxServer.cpp, though i really haven''t tried client/server, why do you have to use AddComponent() prior to the Host() function? thanks,


Because "pDpAddrLocal" is used in the Host function


sorry for my bad englisch.
It''s for a system that has multiple IP addresses. As noted about the multiple AddComponent()s, that''s to specify address and port number. It just cuts out the need for the EnumHost() call. This server component is just my generic base class, but it''s being used for an MMORPG backend I''m designing, where I plan on each server having multiple IP addresses, 1 that''s a valid internet IP, and another IP address that''s used internally for server->server communication.
Advertisement
hi, thanks guys but last question pls!

you specify ip address as ###.###.###.###

uh... how about ports? there are restriction right?
http://www.dualforcesolutions.comProfessional website designs and development, customized business systems, etc.,
The host component can be any valid name that will resolve correctly, or an IP address in dotted notation. If it''s for internal use, the hostname could be resolved by netbios query, wins, dns, lmhosts or hosts file lookup (i.e. anything you can ping from a command prompt). Of course, if it''s going to be something you distribute with a central backend, you''ll want to specify a valid DNS name.

The port component is just a DWORD value. Of course, it''s limited to valid IP ports, 0-65536 I believe.

This topic is closed to new replies.

Advertisement