gusucode.com > 基于VC++的局域网视频聊天系统源码程序 > 基于VC++的局域网视频聊天系统源码程序/code/ChatServer/SocketClient.cpp

    // SocketClient.cpp : implementation file
//

#include "stdafx.h"
#include "ChatServer.h"
#include "SocketClient.h"

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

/////////////////////////////////////////////////////////////////////////////
// CSocketClient

CSocketClient::CSocketClient()
{
	m_user[0].ID.Format("hym");
	m_user[0].PWD.Format("hym000");

	m_user[1].ID.Format("aaa");
	m_user[1].PWD.Format("aaa000");

	m_user[2].ID.Format("bbb");
	m_user[2].PWD.Format("bbb000");

	m_user[3].ID.Format("ccc");
	m_user[3].PWD.Format("ccc000");

	m_szID = _T("");
}

CSocketClient::~CSocketClient()
{
}


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CSocketClient, CSocket)
	//{{AFX_MSG_MAP(CSocketClient)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0

/////////////////////////////////////////////////////////////////////////////
// CSocketClient member functions

//初始化
void CSocketClient::Init(CChatServerDlg * dlg)
{
	m_sfSocketFile = new CSocketFile(this);
	m_aSessionIn = new CArchive(m_sfSocketFile,CArchive::load,4096);
	m_aSessionOut = new CArchive(m_sfSocketFile,CArchive::store,4096);
	m_dlgMain = dlg;
}

//套接字信息接收函数
void CSocketClient::OnReceive(int nErrorCode) 
{
	// TODO: Add your specialized code here and/or call the base class
	do 
	{
		CMesg temp;
		temp.Serialize( *m_aSessionIn );
		GetMessgsInfo(&temp);

	} while( !m_aSessionIn->IsBufferEmpty() );
	CSocket::OnReceive(nErrorCode);
}

//命令解析处理函数
void CSocketClient::GetMessgsInfo(CMesg *msg)
{
	CString str;
	CMesg messg;
	POSITION pos;

	//用户聊天信息的处理
	if(msg->m_szCommand.Compare("Message") == 0 )
	{
			SendMegToUser(m_szID,msg->m_szText,msg->m_szRecObject);
			return;

	}
	
	//用户登陆验证
	if (msg->m_szCommand.Compare("Login") == 0)
	{
		if (msg->m_szRecObject.Compare("Server") == 0)
		{
			for (int i = 0 ; i < 4 ; i++ )
			{
				if(msg->m_szID.Compare(m_user[i].ID) == 0 &&
				   msg->m_szPWD.Compare(m_user[i].PWD)  == 0 )
				{
					//相关更新
					m_szID = msg->m_szID;

					//界面更新
					str = m_szID + " 连接了!\r\n";
					m_dlgMain->SetMessageBox(str);
					
					m_dlgMain->SetOnlineNum(1);
					m_dlgMain->AddUserToList(m_szID);

					m_dlgMain->AddUserInfoToChain(msg->m_szID,msg->m_szIP);

					//向其它用户发送新用户信息
					messg.m_szCommand.Format("NewUser");
					messg.m_szID.Format(m_szID);
					messg.m_szIP.Format(msg->m_szIP);
					messg.m_iOnlineNum = m_dlgMain->m_iUserNum;
					messg.m_szText.Format(" * 系统提示:%s 上线了\r\n",m_szID);
					for(pos=m_dlgMain->GetFirstUserFromCHain();pos!=NULL;)
					{
						CSocketClient * t= (CSocketClient *)m_dlgMain->m_connectionList.GetNext(pos);
						messg.m_szRecObject.Format(t->m_szID);
						t->SendM(&messg);
					}
		
					//返回客户端的信息
					messg.m_szCommand.Format("RLogin");
					messg.m_szRecObject.Format(msg->m_szID);
					messg.m_szText.Format("验证通过");
					SendM(&messg);

					//发送在线列表给新用户
					messg.m_szCommand.Format("UpdateUser");
					messg.m_szRecObject.Format(msg->m_szID);
					messg.m_iOnlineNum = m_dlgMain->m_iUserNum;
					m_dlgMain->UserInfoCopy(messg.m_szText);
					SendM(&messg);

					//用户链表更新
					m_dlgMain->AddUserToChain(this);
					
					break;
				}   
			}
			if (i >= 4)
			{
					messg.m_szCommand.Format("RLogin");
					messg.m_szRecObject.Format(msg->m_szID);
					messg.m_szText.Format("错误的用户名和密码");
					SendM(&messg);
			}
			return;
		}
		return;
	}
}

//发送信息的基本函数
void CSocketClient::SendM(CMesg *msg)
{
	if( m_aSessionOut != NULL)
	{
		msg->Serialize(* m_aSessionOut);
		m_aSessionOut->Flush();
	}
}

//给某用户发送信息的处理
BOOL CSocketClient::SendMegToUser(CString Talker, CString Messgs, CString Talked)
{
	CString str;
	CMesg msg;
	POSITION pos;
	bool SendSelf = false; //是否给自己发信息
	bool SendTalked = false; // 是否给接收方发信息

	str.Format("%s 对 %s 说:%s\r\n",Talker,Talked,Messgs);
	m_dlgMain->SetMessageBox(str);

	for(pos=m_dlgMain->GetFirstUserFromCHain();pos!=NULL;)
	{
		CSocketClient * t= (CSocketClient *)m_dlgMain->m_connectionList.GetNext(pos);
		//给自己发信息
		if ( t->m_szID == Talked )
		{
			//封信息包
			msg.m_szCommand.Format("Message");
			msg.m_szRecObject.Format(Talked);
			msg.m_szText.Format("%s 对 你 说:\r\n%s\r\n ",Talker,Messgs);
			//发送
			t->SendM(&msg);
			SendTalked = true;
			if( SendSelf && SendTalked ) return TRUE;
		}
		if ( t->m_szID == Talker )
		{
			//封信息包
			msg.m_szCommand.Format("Message");
			msg.m_szRecObject.Format(Talker);
			msg.m_szText.Format("你 对 %s 说:\r\n%s\r\n",Talked,Messgs) ;
			//发送
			t->SendM(&msg);
			SendSelf = true;
			if( SendSelf && SendTalked ) return TRUE;
		}	
	}
	//接收方已经离开
	msg.m_szText.Format("%s 用户掉线或者已下线\r\n");
	this->SendM(& msg);
	return FALSE;
}


void CSocketClient::OnClose(int nErrorCode) 
{
	// TODO: Add your specialized code here and/or call the base class
	CString str;
	CMesg mesg;
	//服务器端显示信息
	str.Format(" 提示:%s 下线了\r\n",m_szID);
	m_dlgMain->SetMessageBox(str);
	m_dlgMain->SetOnlineNum(-1); //在线列表人数-1

	m_dlgMain->DelUserFromList(m_szID); //从列表中删除用户
	m_dlgMain->DelUserFromChain(m_szID);//从链表中删除用户
	m_dlgMain->DelUserInfoFromChain(m_szID);
	//向其它用户发送离开用户
	mesg.m_szCommand.Format("SystemMeg");
	mesg.m_szText.Format("* 提示:%s下线了\r\n",m_szID);
	mesg.m_szID = m_szID;
	mesg.m_iOnlineNum = m_dlgMain->m_iUserNum;
	for(POSITION pos=m_dlgMain->GetFirstUserFromCHain();pos!=NULL;)
	{
		CSocketClient * t= (CSocketClient *)m_dlgMain->m_connectionList.GetNext(pos);
		mesg.m_szRecObject.Format(t->m_szID);
		t->SendM(&mesg);
	}
//  SendMessages(" 提示",str); //向在线用户提示用户离开
	delete this;
	
	CSocket::OnClose(nErrorCode);
}