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

📄 chatserver.cpp

📁 网络编程
💻 CPP
字号:
// ChatServer.cpp : implementation file
//

#include "stdafx.h"
#include "Chat Server.h"
#include "ChatServer.h"

#include "MainSheet.h"
#include "ListeningSocket.h"
#include "ClientSocket.h"
#include "pkg.h"

//#include "ClientListCtrl.h"

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

/////////////////////////////////////////////////////////////////////////////
// CChatServer property page

IMPLEMENT_DYNCREATE(CChatServer, CPropertyPage)

CChatServer::CChatServer() : CPropertyPage(CChatServer::IDD)
{
	//{{AFX_DATA_INIT(CChatServer)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	m_pListenSocket = NULL;
	bListening = FALSE;
	m_clientNames = "";
}

CChatServer::~CChatServer()
{
	CloseListening();
	m_clientNames = "";
}

void CChatServer::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CChatServer)
	DDX_Control(pDX, IDC_LIST1, m_ClientListCtrl);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CChatServer, CPropertyPage)
	//{{AFX_MSG_MAP(CChatServer)
	ON_BN_CLICKED(IDC_START, OnStart)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChatServer message handlers

BOOL CChatServer::PreTranslateMessage (MSG* pMsg)
{
	// Let the ToolTip process this message.
	m_tooltip.RelayEvent(pMsg);

	return CPropertyPage::PreTranslateMessage(pMsg);
}

BOOL CChatServer::OnInitDialog()
{
	CPropertyPage::OnInitDialog();

	// Create the ToolTip control.
	m_tooltip.Create (this);
	m_tooltip.Activate (TRUE);

	// TODO: Use one of the following forms to add controls:
	// m_tooltip.AddTool (GetDlgItem (IDC_<name>), <string-table-id>);
	// m_tooltip.AddTool (GetDlgItem (IDC_<name>), _T ("<text>"));

	//set imagelist for the listctrl
	m_imgComputer.Create(16,16,TRUE,1,1);
	m_imgComputer.Add(AfxGetApp()->LoadIcon(IDI_ICON1));

	//start listening
	BeginListening(1500);


	return TRUE;
}

void CChatServer::OnStart() 
{
	// TODO: Add your control notification handler code here
	bListening = !bListening;

	CString strTitle;
	CButton* pButton = (CButton*)GetDlgItem(IDC_START);
	pButton->GetWindowText(strTitle);
	
	if(strTitle == "Start"){
		if(!m_ContactList.IsEmpty()){
			UpdateInfo2All("Server is now starting listening again.",SVRSTART);
		}
		strTitle = "Stop";
		CStatic* pStatic = (CStatic*)GetDlgItem(IDC_IPADDRESS);
		pStatic->SetWindowText(GetServerIP());
		pStatic->EnableWindow(TRUE);
	}
	else{
		UpdateInfo2All(
			" The Server is now stopping listening.But your Link still exists. Pls try again later. Sorry for any inconvinience.",
			SVRSTOP);
		strTitle = "Start";
		CStatic* pStatic = (CStatic*)GetDlgItem(IDC_IPADDRESS);
		pStatic->SetWindowText(GetServerIP());
		pStatic->EnableWindow(FALSE);
	}


	pButton->SetWindowText(strTitle);

}

void CChatServer::SetOwner(CMainSheet *pMainSheet)
{
	m_pMainSheet = pMainSheet;
}

BOOL CChatServer::BeginListening(UINT port)
{
	ASSERT(m_pListenSocket == NULL);
		
	if(!m_ContactList.IsEmpty())
		CloseAllClients();

	m_pListenSocket = new CListeningSocket(this);
	m_pListenSocket->Create(port);
//	bListening = TRUE;
	return m_pListenSocket->Listen();
//		((CEditView*)m_viewList.GetHead())->SetWindowText(_T("Begin listening ..."));
}

void CChatServer::ProcessClientPkg(CClientSocket *pSocket)
{
	CPkg pkg;
	ASSERT(pSocket);
	
	try{
		
		// the next line of code was first not included in the bListening == FALSE block
		// and caused some error: for that part the Archive buffer was just full.
		// Now I moved it outside of the if-else block so that it applys both parts.
		pSocket->ReceivePkg(&pkg);
		if(bListening){
			if(pkg.request == NEW){
				if(IsThisNameBeingUsed(pkg,pSocket)){
					Server2Indivisual(pSocket,"Sorry. The screen name is being used. Try using another one.Thank you.",SIGNOUT);
					return;
				}

				UpdateClientInfo(&pkg,pSocket);
				CString strReminder;
				strReminder.Format("%s  just signed in.", pkg.strName);

				UpdateListCtrl();
				UpdateInfo2All(strReminder,NEW);

				// log message sent to the log page
				CTime time= CTime::GetCurrentTime();;
				CString strTmp = time.Format(" Time is:  %H:%M:%S. Date is: %A, %B %d, %Y");
				strReminder += strTmp;
				m_pMainSheet->SetLogMessage(strReminder);
				
			}
			if(pkg.request == OFF){
				CString strReminder;
				strReminder.Format("%s  just logged off.", pkg.strName);

				DeleteIndivisual(pkg.strName);
				UpdateListCtrl();
				UpdateInfo2All(strReminder,OFF);
				
				// log message sent to the log page
				CTime time= CTime::GetCurrentTime();;
				CString strTmp = time.Format(" Time is:  %H:%M:%S. Date is: %A, %B %d, %Y");
				strReminder += strTmp;
				m_pMainSheet->SetLogMessage(strReminder);
			}
			if(pkg.request == MESG ){
				UpdateClientInfo(&pkg,pSocket);
				Send2AllClients(&pkg);
			}
		}
	}
	catch(CFileException* e){
		TCHAR szCause[255];
		e->GetErrorMessage(szCause,255);
		AfxMessageBox(szCause);
	}
}

void CChatServer::Send2AllClients(CPkg *pkg)
{
	for(POSITION pos = m_ContactList.GetHeadPosition(); pos != NULL;){
		CPkg* pClient = (CPkg*)m_ContactList.GetNext(pos);
		ASSERT(pClient);
		CClientSocket* pSocket = (CClientSocket*)pClient->pSocket;
		ASSERT(pSocket);	
		try{
			pSocket->SendPkg(pkg);
		}
		catch(CFileException* e){
			TCHAR szCause[255];
			e->GetErrorMessage(szCause,255);
			AfxMessageBox(szCause);
		}
	}
}

void CChatServer::CloseAllClients()
{
	for(POSITION pos = m_ContactList.GetHeadPosition();pos != NULL;){
		CPkg* pClient = (CPkg*)m_ContactList.GetNext(pos);
		ASSERT(pClient);
		CClientSocket* pSocket = (CClientSocket*)pClient->pSocket;
		pSocket->Close();
		if(pSocket != NULL) {delete pSocket;pSocket = NULL;}
		//		pSocket->Finalize();
		delete pClient;
		pClient = NULL;
	}
	m_ContactList.RemoveAll();
}

void CChatServer::CloseListening()
{
	if(m_pListenSocket == NULL) return ;

	//close the linked client and clear up the contact list
	CloseAllClients();
	m_pListenSocket->Close();
	delete m_pListenSocket;
	m_pListenSocket = NULL;
	bListening = FALSE;
}


//when got a connection message from a client
void CChatServer::ProcessAccept()
{
	CClientSocket* pSocket = new CClientSocket(this);
	m_pListenSocket->Accept(*pSocket);
	pSocket->Init();

	CString ipAddress;
	UINT port;
	pSocket->GetPeerName(ipAddress,port);	
	


	//send the connection confirmation to the client,add to the list - yh
	CPkg pkg;
	pkg.Init();
	pkg.strName = _T("Server");
	pkg.strText = "Connected. Please Sign in now ...";
	pkg.clrText = RGB(0,0,0);
	pkg.bBold = 1;//bold
	pkg.fontName = "system";
	pkg.fontSize = 12;
	pkg.clrText = RGB(0,0,255);//blue
	pkg.request = CONN;

	pSocket->SendPkg(&pkg);



	CPkg* pTmp;
	pTmp = new CPkg;
	ASSERT(pTmp);

	pTmp->Init();
	pTmp->ipAddress = ipAddress;
	pTmp->port = port;
	pTmp->pSocket = (DWORD)pSocket;

	if(m_ContactList.IsEmpty()){
		m_ContactList.AddHead(pTmp);
	}
	else{
		m_ContactList.AddTail(pTmp);
	}
}



BOOL CChatServer::IsThisNameBeingUsed(CPkg& pkg,CClientSocket* pSocket)
{
	if(m_ContactList.IsEmpty()) return TRUE;
	
	CString name = pkg.strName;
//	CClientSocket* pSocket = (CClientSocket*)pkg.pSocket;
	ASSERT(pSocket);

	for(POSITION pos = m_ContactList.GetHeadPosition();pos != NULL;){
		CPkg* pPkg = (CPkg*)m_ContactList.GetNext(pos);
		ASSERT(pPkg);
		if(name == "Server") return TRUE; // this name is used by server only!
		if(name == pPkg->strName && pSocket != (CClientSocket*)pPkg->pSocket) return TRUE;
	}
	return FALSE;
}

void CChatServer::Server2Indivisual(CString name, CString strMessage,int request)
{
	for(POSITION pos = m_ContactList.GetHeadPosition(); pos != NULL;){
		CPkg* pClient = (CPkg*)m_ContactList.GetNext(pos);
		ASSERT(pClient);
		if(pClient->strName != name) continue;
		try{
			CClientSocket* pSocket = (CClientSocket*)pClient->pSocket;
			ASSERT(pSocket);	
		
			CPkg pkg;
			pkg.Init();
			pkg.strName = _T("Server");
			pkg.strText = strMessage;
			pkg.clrText = RGB(0,0,0);
			pkg.bBold = 1;//bold
			pkg.clrText = RGB(0,0,255);//blue
			pkg.fontName = "system";
			pkg.fontSize = 12;
			pkg.request = request;
			pSocket->SendPkg(&pkg);

		}
		catch(CFileException* e){
			TCHAR szCause[255];
			e->GetErrorMessage(szCause,255);
			AfxMessageBox(szCause);
		}
	}
}

void CChatServer::Server2Indivisual(CClientSocket* pSocket, CString strMessage,int request)
{
	for(POSITION pos = m_ContactList.GetHeadPosition(); pos != NULL;){
		CPkg* pClient = (CPkg*)m_ContactList.GetNext(pos);
		ASSERT(pClient);
		if((CClientSocket*)pClient->pSocket != pSocket) continue;
		try{
			CClientSocket* pSocket = (CClientSocket*)pClient->pSocket;
			ASSERT(pSocket);	
		
			CPkg pkg;
			pkg.Init();
			pkg.strName = _T("Server");
			pkg.strText = strMessage;
			pkg.clrText = RGB(0,0,0);
			pkg.bBold = 1;//bold
			pkg.fontSize = 12;
			pkg.clrText = RGB(0,0,255);//blue
			pkg.fontName = "system";
			pkg.request = request;
			pSocket->SendPkg(&pkg);

		}
		catch(CFileException* e){
			TCHAR szCause[255];
			e->GetErrorMessage(szCause,255);
			AfxMessageBox(szCause);
		}
	}
}

void CChatServer::UpdateInfo2All(CString msg,int request)
{
	CPkg pkg;
	CString nameString = "";

	for(POSITION pos = m_ContactList.GetHeadPosition(); pos != NULL;){

		CPkg* pClient = (CPkg*)m_ContactList.GetNext(pos);
		nameString += pClient->strName;
		nameString += ";";
	}
	for(pos = m_ContactList.GetHeadPosition(); pos != NULL;){
		
		CPkg* pClient = (CPkg*)m_ContactList.GetNext(pos);

		pkg.bBold = 1;//bold
		pkg.clrText = RGB(0,0,255);//blue
		pkg.strName = nameString;
		pkg.strText = msg;
		pkg.request = request;

		try{
			CClientSocket* pSocket = (CClientSocket*)pClient->pSocket;
			ASSERT(pSocket);	
			pSocket->SendPkg(&pkg);

		}
		catch(CFileException* e){
			TCHAR szCause[255];
			e->GetErrorMessage(szCause,255);
			AfxMessageBox(szCause);
		}		
	}
	nameString = "";
}

void CChatServer::UpdateClientInfo(CPkg* pPkg,CClientSocket* pSocket)
{
	ASSERT(pSocket);
	ASSERT(pPkg);
//	CString name = pPkg->strName;
	
	for(POSITION pos = m_ContactList.GetHeadPosition();pos != NULL;){
		CPkg* pTmp = (CPkg*)m_ContactList.GetNext(pos);
		if(pSocket == (CClientSocket*)pTmp->pSocket){

			pTmp -> strText		= pPkg->strText;	//update the pkg info from client
			pTmp -> strName		= pPkg->strName;
			pTmp -> bAway		= pPkg->bAway;
			pTmp -> iMyIcon		= pPkg->iMyIcon;
			pTmp -> bBold		= pPkg->bBold ;
			pTmp -> bItalic		= pPkg-> bItalic;
			pTmp -> bUnderLine  = pPkg->bUnderLine;
			pTmp -> bStrikeOut	= pPkg->bStrikeOut;
			pTmp -> clrText		= pPkg->clrText;
			pTmp -> fontName	= pPkg->fontName;
			pTmp -> fontSize	= pPkg->fontSize;

//			pTmp -> ipAddress	= pPkg->ipAddress;
//			pTmp -> port		= pPkg->port;
//			pTmp -> request		= pPkg->request;
//			pTmp -> pSocket		= pPkg->pSocket;
			pPkg->ipAddress = pTmp->ipAddress;
			pPkg->port = pTmp->port;
			pPkg->pSocket = pTmp->pSocket;

			return ; //successful in update
		}
	}

}

void CChatServer::DeleteIndivisual(CString name)
{
	for(POSITION pos = m_ContactList.GetHeadPosition();pos != NULL;){
		CPkg* pClient = (CPkg*)m_ContactList.GetAt(pos);
		ASSERT(pClient);
		if(pClient->strName == name){
			m_ContactList.RemoveAt(pos);
			CClientSocket* pSocket = (CClientSocket*)pClient->pSocket;
			pSocket->Close();
			delete pSocket;
			pSocket = NULL;
			delete pClient;
			pClient = NULL;
			break;
		}
		else{
			m_ContactList.GetNext(pos);
		}
	}
}

void CChatServer::UpdateListCtrl()
{
	m_ClientListCtrl.DeleteAllItems();
	m_ClientListCtrl.SetImageList(&m_imgComputer,LVSIL_SMALL);
	LV_ITEM lvItem;
	
	int iActualItem,iItem,iSub;

	int length = m_ContactList.GetCount();
	for(iItem=0;iItem<length;iItem++){
		CPkg* pTmp = (CPkg*)m_ContactList.GetAt(m_ContactList.FindIndex(iItem));
		LPTSTR ipAddress = (pTmp->ipAddress).GetBuffer(pTmp->ipAddress.GetLength());
		CString tmp;
		tmp.Format("%d",pTmp->port);
		LPTSTR port = tmp.GetBuffer(tmp.GetLength());

		for(iSub = 0;iSub<3;iSub++){
			lvItem.mask = LVIF_TEXT|(iSub == 0? LVIF_IMAGE:0);
			lvItem.iItem = (iSub == 0)? iItem : iActualItem;
			lvItem.iSubItem  = iSub;
			lvItem.iImage = 0;
			lvItem.pszText = "";	//even you don't need this member,still declare it!
			if(iSub == 0)
	    		 iActualItem = m_ClientListCtrl.InsertItem(&lvItem);
			else{
				if(iSub == 1)
					lvItem.pszText  = ipAddress;
				else if(iSub == 2)
					lvItem.pszText = port;
				m_ClientListCtrl.SetItem(&lvItem);
			}
		}
	}
}

CString CChatServer::GetServerIP()
{
	char szHostName[200];
	gethostname(szHostName,strlen(szHostName));
	LPHOSTENT pHost;
	pHost = gethostbyname(szHostName);
	struct in_addr* ptr = (struct in_addr*)pHost->h_addr_list[0];
	int a = ptr->S_un.S_un_b.s_b1;
	int b = ptr->S_un.S_un_b.s_b2;
	int c = ptr->S_un.S_un_b.s_b3;
	int d = ptr->S_un.S_un_b.s_b4;
	
	CString strTmp;
	strTmp.Format("%d.%d.%d.%d",a,b,c,d);
	return strTmp;

}

⌨️ 快捷键说明

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