⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 instantmessageserver.cpp

📁 c++系统开发实例精粹内附的80例源代码 环境:windows2000,c++6.0
💻 CPP
字号:
//////////////////////////////////////////////////////////////////////
// FileFury
// Copyright (c) 2000 Tenebril Incorporated
// All rights reserved.
//
// This source code is governed by the Tenebril open source
// license (http://www.tenebril.com/developers/opensource/license.html)
//
// For more information on this and other open source applications,
// visit the Tenebril OpenSource page:
//       http://www.tenebril.com/developers/opensource
//
//////////////////////////////////////////////////////////////////////

// InstantMessageServer.cpp: implementation of the CInstantMessageServer class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Oscar.h"
#include "InstantMessageServer.h"

#include "AwareNetDivers.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

static HANDLE handleThread;

#define _afxSockThreadState AfxGetModuleThreadState()
#define _AFX_SOCK_THREAD_STATE AFX_MODULE_THREAD_STATE

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CInstantMessageServer::CInstantMessageServer()
{

}

CInstantMessageServer::~CInstantMessageServer()
{

}

BOOL CInstantMessageServer::Start()
{
	CWinThread *pThread;

	if(handleThread)
		return FALSE;

	m_bStayOn = TRUE;

	pThread = AfxBeginThread((AFX_THREADPROC)(CInstantMessageServer::DriveWork),
		(LPVOID)this, THREAD_PRIORITY_LOWEST);

	ASSERT(pThread);
	if(!pThread) return FALSE;

	handleThread = pThread->m_hThread;

	return TRUE;
}

BOOL CInstantMessageServer::Stop(BOOL bWait)
{
	DWORD dwExitCode = STILL_ACTIVE;

	if(!handleThread)
		return FALSE;

	m_bStayOn = FALSE;

	while(dwExitCode == STILL_ACTIVE && bWait)
	{
		if(!GetExitCodeThread(handleThread, &dwExitCode))
			return FALSE;

		if(dwExitCode == STILL_ACTIVE)
			Sleep(THREAD_DIE_WAIT);
	}

	return TRUE;
}

UINT PASCAL CInstantMessageServer::DriveWork(LPVOID *Param)
{
	CInstantMessageServer *pThis;

	// Jump into the object itself
	pThis = (CInstantMessageServer *)Param;
	if(!pThis)
	{
		handleThread = NULL;     // Clear the global handle
		return 0;
	}

	// Initialize this thread's AFX socket stuff (hack for VC6)
#ifdef PER_THREAD_SOCKINIT
	{
		_AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
		if (pState->m_pmapSocketHandle == NULL)
			pState->m_pmapSocketHandle = new CMapPtrToPtr;
		if (pState->m_pmapDeadSockets == NULL)
			pState->m_pmapDeadSockets = new CMapPtrToPtr;
		if (pState->m_plistSocketNotifications == NULL)
			pState->m_plistSocketNotifications = new CPtrList;
	}
#endif

	// Set up the receiving socket
	CTimeoutSocket *sock = new CTimeoutSocket;
	UINT nLoopCheck = 0;
	while(!sock->Create(PORT_OSCARIM))
	{
		Sleep(SOCKET_TIMEOUT);  // Probably just restarted after a close
		nLoopCheck += 1;
		if(nLoopCheck > SOCKET_RETRY_LIMIT)
			return 0;
	}

	sock->Listen(IM_LISTEN_BUFFER);

	CTimeoutSocket *sockClient = NULL;
	while(pThis->m_bStayOn)
	{
		// Handle a connection

		if(sockClient)                         // Can't reuse sockets?
			delete sockClient;

		sockClient = new CTimeoutSocket;

		// This will fall through each time the socket times out; it will
		// keep this thread from stalling.
		BOOL bAccepted;
		sock->SetTimeout(SOCKET_TIMEOUT);
		bAccepted = sock->Accept(*sockClient);

		if(bAccepted)
		{
			// Get the instant message.
			IMPacketStruct imPacket;
			memset((void *)&imPacket, 0, sizeof(IMPacketStruct));
			if(sockClient->ReceiveFull((void *)&imPacket, sizeof(IMPacketStruct)) !=
				sizeof(IMPacketStruct))
			{
				// Didn't work; bail.
				sockClient->Close();
				continue;
			}

			// Get the sender's IP address.
			CString cszPeerIP;
			UINT nPeerPort;
			if(!sockClient->GetPeerName(cszPeerIP, nPeerPort))
			{
				// For some reason, couldn't get the peer IP address.
				sockClient->Close();
				continue;
			}

			// Close the socket.
			sockClient->Close();

			// Get the app.
			COscarApp *pApp = (COscarApp *)AfxGetApp();
			ASSERT(pApp);

			// Add the instant message.
			pApp->AddInstantMessage(cszPeerIP, (LPCTSTR)imPacket.tczSenderName,
				(LPCTSTR)imPacket.tczMessage, imPacket.crBack, imPacket.crText);

			// Done.
		}

		// Keep working until the StayOn flag goes down
	}

	// Clean up memory.
	sock->Close();
	delete sock;
	if(sockClient) delete sockClient;

	// Clean up
	handleThread = NULL;
	return 1;
}

BOOL PASCAL CInstantMessageServer::SendMessage(LPCTSTR czDest, LPCTSTR czMessage,
											   LPCTSTR czDestName)
{
	CString cszDest = czDest;
	CString cszMessage = czMessage;
	CString cszDestName = czDestName;
	CString cszFullDest = czDest;

	// Make sure we have both strings.
	if(cszDest.GetLength() == 0 || cszMessage.GetLength() == 0)
		return FALSE;

	// Get a handle to AwareNet.
	CAwareNet cANet;

	// Get a handle to the app.
	COscarApp *pApp = (COscarApp *)AfxGetApp();
	ASSERT(pApp);

	// Resolve the destination.
	if(cszDest.Find(_T('@')) > -1)  // E-mail address; use AwareNet.
	{
		CString cszDestIP;

		// Check to make sure AwareNet has been initialized.
		if(!pApp->m_bANetInit)
		{
			// Wouldn't be able to resolve the e-mail address.  Bail.
			return FALSE;
		}

		if(!AwareNet_FindIP(&cANet, cszDest, cszDestIP, FALSE))
		{
			// Couldn't resolve the e-mail address.  Bail.
			return FALSE;
		}

		cszDest = cszDestIP;
	}

	// Get our name.
	CString cszMyName;
	if(!AwareNet_GetMyName(&cANet, cszMyName))
		return FALSE;

	// Construct the packet.
	IMPacketStruct imPacket;

	// Default colors.
	imPacket.crBack = RGB(128, 128, 255);
	imPacket.crText = RGB(0, 0, 0);
	
	// Get the user's colors.
	CSettingsArchive *pArchive = pApp->GetArchive();
	ASSERT(pArchive);
	if(pArchive)
	{
		imPacket.crBack = pArchive->m_arch2.crMyBubble;
		imPacket.crText = pArchive->m_arch2.crMyText;
	}

	// Truncate the message to fit in the packet and copy it.
	cszMessage = cszMessage.Left(sizeof(imPacket.tczMessage) / sizeof(TCHAR) - 1);
	memcpy((void *)imPacket.tczMessage, (void *)cszMessage.GetBuffer(0),
		sizeof(TCHAR) * (cszMessage.GetLength() + 1));

	// Truncate the name to fit in the packet and copy it.
	cszMyName = cszMyName.Left(sizeof(imPacket.tczSenderName) / sizeof(TCHAR) - 1);
	memcpy((void *)imPacket.tczSenderName, (void *)cszMyName.GetBuffer(0),
		sizeof(TCHAR) * (cszMyName.GetLength() + 1));

	// Open a connection to the destination machine.
	CTimeoutSocket sock;
	if(!sock.Create())
	{
		ASSERT(0);      // Should not happen.
		return FALSE;
	}

	if(!sock.Connect(cszDest, PORT_OSCARIM))
		return FALSE;

	// Push the packet.
	if(!sock.Send((void *)&imPacket, sizeof(imPacket)))
		return FALSE;

	// Close the socket.
	sock.Close();

	// Get the best friend's-name representation.
	if(cszDestName.GetLength() > 0)
		cszFullDest = cszDestName;

	// Add the message to our own window.
	pApp->AddInstantMessage(_T("127.0.0.1"), cszFullDest, cszMessage,
		imPacket.crBack, imPacket.crText, TRUE);

	// Done.
	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -