📄 instantmessageserver.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 + -