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