C++写的一个聊天室代码,用于XEIM开源即时通讯软件上的
// C++寫的一個(gè)聊天室代碼,用于XEIM開源即時(shí)通訊軟件上的,歡迎大家一起交流。
// XEIM_ChatroomDlg.cpp : implementation file
// [即時(shí)通訊軟件],[XEIM],[飛鴿傳書]
#include "stdafx.h"
#include "xeim.h"
#include "xeimDlg.h"
#include "XEIM_ChatroomDlg.h"
#include "XEIM_Text.h"
#include "XEIM_Message.h"
#include "XEIM_ChatDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CXEIM_ChatroomDlg dialog
CXEIM_ChatroomDlg::CXEIM_ChatroomDlg(CWnd* pParent /*=NULL*/)
?: CDialog(CXEIM_ChatroomDlg::IDD, pParent)
{
?//{{AFX_DATA_INIT(CXEIM_ChatroomDlg)
??// NOTE: the ClassWizard will add member initialization here
?m_bServerRunning = FALSE;
?m_hServer = INVALID_HANDLE_VALUE;
?//}}AFX_DATA_INIT
?m_hIcon = AfxGetApp()->LoadIcon(IDI_ICONCHAT);
}
CXEIM_ChatroomDlg::CXEIM_ChatroomDlg(LPCTSTR lpszUID, CWnd* pParent/* = NULL*/)
{
?m_hIcon = AfxGetApp()->LoadIcon(IDI_ICONCHAT);
?m_bServerRunning = FALSE;
?m_hServer = INVALID_HANDLE_VALUE;
?CString strUID = lpszUID;
?if (! strUID.IsEmpty())
?{
??m_bServerRunning = TRUE;
??if (! m_client.xConnect(M()->T.GetContactIP(lpszUID), 9989))
??{
???MessageBox(m_client.m_strLastError);
???return;
??}
??else
??{
???DWORD dwTID;
???m_client.SetWnd(this);
???HANDLE hThread = CreateThread(NULL, 0, SockRecvProc, (LPVOID)&m_client, 0, & dwTID);
???if (NULL == hThread)
???{
????MessageBox("CreateThread(NULL, 0, CreateHTML_Proc, (LPVOID)m_client, 0, & dwTID) failed.");
????return;
???}
???m_mapClient.insert(pair<HANDLE, CXEIMSocket*>(hThread, &m_client));
??}
?}
}
void CXEIM_ChatroomDlg::AddRecvText(LPCTSTR lpszUser, LPCTSTR lpszData)
{
?CTime m_StartTime1 = CTime::GetCurrentTime();
?CString csStartTime;
?// 信息 發(fā)送者 和 發(fā)送時(shí)間
?csStartTime.Format(_T("%s - %s/r/n"), M()->T.GetContactDisplayName(lpszUser),
??m_StartTime1.Format(_T("%H:%M:%S")));
?//
?int iTotalTextLength = m_richMsg.GetWindowTextLength();
?m_richMsg.SetSel(iTotalTextLength, iTotalTextLength);
?m_richMsg.ReplaceSel(csStartTime);
?int iStartPos = iTotalTextLength;
?CHARFORMAT cf;
?cf.cbSize = sizeof(CHARFORMAT);
?cf.dwMask = CFM_COLOR | CFM_UNDERLINE | CFM_BOLD;
?cf.dwEffects = (unsigned long)~(CFE_AUTOCOLOR | CFE_UNDERLINE | CFE_BOLD);
?cf.crTextColor = RGB(0, 128, 0);
?int iEndPos = m_richMsg.GetWindowTextLength();
?m_richMsg.SetSel(iStartPos, iEndPos);
?m_richMsg.SetSelectionCharFormat(cf);
?m_richMsg.SetSel(iEndPos, iEndPos);
?CString str = lpszData;
?int nIdx = 0;
?while (nIdx != -1)
?{
??nIdx = str.Find('/n', nIdx+1);
??str.Insert(nIdx+1, "? ");
?}
?str += "/r/n";
?m_richMsg.ReplaceSel(str);
?m_richMsg.SetSel(iEndPos, m_richMsg.GetWindowTextLength());
?cf.crTextColor = RGB(0, 0, 0);
?m_richMsg.SetSelectionCharFormat(cf);
?m_richMsg.PostMessage(WM_VSCROLL, SB_BOTTOM,0);
/*?m_editAllMessage += lpszUser;
?m_editAllMessage += "/r/n";
?m_editAllMessage += lpszData;
?UpdateData(FALSE);
?AfxMessageBox(lpszData);*/
}
void CXEIM_ChatroomDlg::OnAcceptClose()
{
//?AfxMessageBox("asdf");
}
void CXEIM_ChatroomDlg::OnRecvData(WPARAM wParam, LPARAM lParam)
{
?CXEIMSocket *pclient = (CXEIMSocket*)lParam;
?CXEIMData *pData = (CXEIMData*)wParam;
//?AfxMessageBox(pData->GetData());
?if (pData->GetMessage() == 2)
?{
??CString strData = pData->GetData();
??UINT nLeft = strData.Find("|");
??CString strUID = strData.Left(nLeft);
??CString strText = strData.Right(strData.GetLength()-nLeft-1);
??AddRecvText(strUID, strText);
??if (m_bServerRunning) {
???map<HANDLE, CXEIMSocket*>::iterator _beg=m_mapClient.begin(),
????_end=m_mapClient.end();
???for (; _beg != _end; _beg++)
???{
????_beg->second->xSend(pData->GetData(), pData->GetDataLength());
???}
??}
?}
?else if (pData->GetMessage() == 1)
?{
??CString strData = pData->GetData();
??CString strRight = strData;
??UINT nIdx = strData.Find("|");
??while (-1 != nIdx)
??{
???CString strUser = strRight.Left(nIdx);
???m_listboxUser.AddString(strUser);
???CString strk;
???strk.Format("%s - %d,%d",strData, nIdx, strData.GetLength());
???strRight = strRight.Right(strRight.GetLength()-nIdx-1);
???nIdx = strRight.Find("|");
??}
?}
?delete pData;
}
void CXEIM_ChatroomDlg::OnNewClient(WPARAM wParam, LPARAM lParam)
{
?CXEIMSocket *pClient = new CXEIMSocket((SOCKET)wParam, (CWnd*)lParam);
?DWORD dwTID;
?HANDLE hThread = CreateThread(NULL, 0, SockRecvProc, (LPVOID)pClient, 0, & dwTID);
?if (NULL == hThread)
?{
??MessageBox("CreateThread(NULL, 0, CreateHTML_Proc, (LPVOID)this, 0, & dwTID) failed.");
??return;
?}
?m_mapClient.insert(pair<HANDLE, CXEIMSocket*>(hThread, pClient));
?CString strUsers;
?int nCount = m_listboxUser.GetCount(); // 得到項(xiàng)目總數(shù)
?for(int i=0; i<nCount; ++ i)
?{
??CString strText;
??m_listboxUser.GetText(i, strText);
??strUsers += strText;
??strUsers += "|";
?}
?pClient->xSend1(strUsers, strUsers.GetLength()+1);
//?MessageBox(pClient->GetHostAddress());
}
void CXEIM_ChatroomDlg::DoDataExchange(CDataExchange* pDX)
{
?CDialog::DoDataExchange(pDX);
?//{{AFX_DATA_MAP(CXEIM_ChatroomDlg)
?DDX_Control(pDX, IDC_RICHEDIT1, m_richMsg);
?DDX_Control(pDX, IDC_LIST1, m_listboxUser);
?//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CXEIM_ChatroomDlg, CDialog)
?//{{AFX_MSG_MAP(CXEIM_ChatroomDlg)
?ON_MESSAGE(WM_SERVER_CREATED, OnServerCreated)
?ON_MESSAGE(WM_ACCEPT_CLOSE, OnAcceptClose)
?ON_MESSAGE(WM_NEW_CLIENT, OnNewClient)
?ON_MESSAGE(WM_RECV_DATA, OnRecvData)
?ON_BN_CLICKED(IDC_SEND, OnSend)
?ON_MESSAGE(XM_EMDBLCLICKTREE, XDoubleClickUserList)
?//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CXEIM_ChatroomDlg message handlers
void CXEIM_ChatroomDlg::OnOK()
{
?// TODO: Add extra validation here
?CDialog::OnOK();
}
void CXEIM_ChatroomDlg::OnCancel()
{
?// TODO: Add extra cleanup here
?
?CDialog::OnCancel();
}
void CXEIM_ChatroomDlg::OnSend()
{
?// TODO: Add your control notification handler code here
/*?UpdateData();
?if (m_editSend.IsEmpty())
?{
??AfxMessageBox("請輸入要發(fā)送的消息");
??return;
?}
?if (! m_bServerRunning) { // 客戶端
??m_client.xSend(m_editSend, m_editSend.GetLength()+1);
?}
?else // 服務(wù)端
?{
??map<HANDLE, CXEIMSocket*>::iterator _beg=m_mapClient.begin(),
???_end=m_mapClient.end();
??for (; _beg != _end; _beg++)
??{
???_beg->second->xSend(m_editSend, m_editSend.GetLength()+1);
??}
??AddRecvText("Server", m_editSend);
?}
?m_editSend = "";
?UpdateData(FALSE);*/
?CString str;
?GetDlgItemText(IDC_RICHEDIT2, str);
?if(str.IsEmpty())
?{
??MessageBox("請輸入消息內(nèi)容!");
??return;
?}
?if (str.GetLength() > 1024 - 100)
?{
??CString str2;
??str2.Format(_T("你所發(fā)的信息太長,請分幾次發(fā)送,最大 1024 個(gè)字符。"), str.GetLength());
??MessageBox(str2, _T("警告"), MB_ICONINFORMATION);
??return;
?}
?CString strSend;
?strSend.Format(_T("%s|%s"), M()->T.GetLocalUID(), str);
?if (! m_bServerRunning)
?{
??m_client.xSend(strSend, strSend.GetLength()+1);
?}
?else
?{
??map<HANDLE, CXEIMSocket*>::iterator
???_beg=m_mapClient.begin(),
???_end=m_mapClient.end();
??for (; _beg != _end; _beg++)
??{
???_beg->second->xSend(strSend, strSend.GetLength()+1);
??}
??AddRecvText(M()->T.GetLocalUID(), str);
?}
?SetDlgItemText(IDC_RICHEDIT2, "");
//?m_client.xSend("33",3);
}
void CXEIM_ChatroomDlg::OnServerCreated(WPARAM wParam, LPARAM lParam)
{
?XEIM _p = M();
?CString strFileString;
?strFileString.Format(_T("%s|%s"), XEIM_CHATROOM, m_strChatroomName);
/*?map<HTREEITEM, XEIM_User*>::iterator imap
??= _p->m_chatroomUsers.begin(),
??_end = _p->m_chatroomUsers.end();
?// 讀取聊天室成員
?for (; imap!=_end; ++imap) {
??CXEIM_Text xText(imap->second->GetUID(), strFileString);
??// 獲取用戶聯(lián)系人
??XEIM_Message toSend("forward",xText.GetBuffer());
?//?AfxMessageBox(toSend.GetData());
??if(! _p->m_iocp.BuildPackageAndSend(_p->m_serverSocket,Job_UserData,toSend.GetBuffer()))
??{
???AfxMessageBox("Send not successfull.!");
??}
?//?int nIndex = m_listboxUser.AddString(imap->second->GetDisplayName());
?//?m_listboxUser.SetItemData(nIndex, imap->first);
?}*/
}
BOOL CXEIM_ChatroomDlg::OnInitDialog()
{
?CDialog::OnInitDialog();
?
?// Set the icon for this dialog.? The framework does this automatically
?//? when the application's main window is not a dialog
?SetIcon(m_hIcon, TRUE);???// Set big icon
?SetIcon(m_hIcon, FALSE);??// Set small icon
?// TODO: Add extra initialization here
?// 設(shè)置聊天室名稱
?CString strRoomname;
?strRoomname.Format(_T("%s - 聊天室"), m_strChatroomName);
?SetWindowText(strRoomname);
?// 創(chuàng)建 聊天室服務(wù)器 線程
/*?if (! m_bServerRunning)
?{
??// 聊天是首先要有自己
??CString strSelfName = M()->GetLocalDisplayName();
??strSelfName += _T("(主機(jī))");
??int nIndex = m_listboxUser.AddString(strSelfName);
??m_listboxUser.SetItemData(nIndex, 0);
??m_bServerRunning = TRUE;
??DWORD dwTID;
??m_hServer = CreateThread(NULL, 0, ServerThreadProc, (LPVOID)this, 0, & dwTID);
??if (NULL == m_hServer)
??{
???AfxMessageBox("CreateThread(NULL, 0, CreateHTML_Proc, (LPVOID)this, 0, & dwTID) failed.");
???return TRUE;
??}
??map<SOCKET, XEIM_User*>::iterator imap
??= M()->m_chatroomUsers.begin(),
??_end = M()->m_chatroomUsers.end();
??// 讀取聊天室成員
??for (; imap!=_end; ++imap) {
???int nIndex = m_listboxUser.AddString(imap->second->GetDisplayName());
???m_listboxUser.SetItemData(nIndex, imap->first);
??}
?}
?else
?{
??m_bServerRunning = ! m_bServerRunning;
?}
*/
?return TRUE;? // return TRUE unless you set the focus to a control
?????????????? // EXCEPTION: OCX Property Pages should return FALSE
}
?
DWORD CALLBACK CXEIM_ChatroomDlg::SockRecvProc(LPVOID lParam)
{
?CXEIMSocket *pclient = (CXEIMSocket*)lParam;
?CXEIM_ChatroomDlg *pDlg = (CXEIM_ChatroomDlg*)pclient->GetWnd();
//?::MessageBox(NULL,"","",MB_OK);
?while(1)
?{
??UINT nLen = 0;
??char * buf = pclient->xRecv(nLen);
??if (nLen > 0)
??{
???CXEIMData *pData = new CXEIMData(buf, nLen);
???if (pDlg)
????pDlg->PostMessage(WM_RECV_DATA, (WPARAM)pData, (LPARAM)pclient);
??}
??delete buf;
?}
?pclient->xShutdown(SD_BOTH);
?pclient->xCloseSocket();
?return -1;
}
DWORD CALLBACK CXEIM_ChatroomDlg::ServerThreadProc(LPVOID lParam)
{
?CXEIM_ChatroomDlg *pDlg = (CXEIM_ChatroomDlg*)lParam;
??? //最好不要使用aSocket.Create創(chuàng)建,因?yàn)槿菀讜?huì)出現(xiàn)10048錯(cuò)誤
?pDlg->m_svrSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
??? if (INVALID_SOCKET == pDlg->m_svrSocket)
??? {
??????? char szError[256] = {0};
??????? sprintf(szError, "Create Faild: %d", WSAGetLastError());
??????? AfxMessageBox(szError);
??????? return -1;
??? }
??? BOOL bOptVal = TRUE;
??? int bOptLen = sizeof(BOOL);
??? //設(shè)置Socket的選項(xiàng), 解決10048錯(cuò)誤必須的步驟
?setsockopt(pDlg->m_svrSocket, SOL_SOCKET, SO_REUSEADDR, (LPSTR)&bOptVal, bOptLen);
?? // pDlg->m_svrSocket.SetSockOpt(SO_REUSEADDR, (void *)&bOptVal, bOptLen, SOL_SOCKET);
?SOCKADDR_IN local;
?memset(&local, 0, sizeof(SOCKADDR_IN));
?local.sin_addr.s_addr = htonl(INADDR_ANY);
?local.sin_family = AF_INET;
?local.sin_port = htons(9989);
?int ret = bind(pDlg->m_svrSocket, (PSOCKADDR)&local, sizeof(SOCKADDR_IN));
?//綁定端口
??? if (SOCKET_ERROR == ret)
??? {
??????? char szError[256] = {0};
??????? sprintf(szError, "Bind Faild: %d", WSAGetLastError());
??????? AfxMessageBox(szError);
??????? return -1;
??? }
??? //監(jiān)聽
?ret = listen(pDlg->m_svrSocket, 10);
??? if(SOCKET_ERROR == ret)
??? {
??????? char szError[256] = {0};
??????? sprintf(szError, "Listen Faild: %d", WSAGetLastError());
??????? AfxMessageBox(szError);
??????? return -1;
??? }
?// 通知上級(jí)線程 線程服務(wù)可以開始了
?pDlg->PostMessage(WM_SERVER_CREATED);
?while (pDlg->m_bServerRunning)
?{
??// 接收外部連接
??int iAddress = sizeof(SOCKADDR_IN);
??SOCKET sClient;
??SOCKADDR_IN addrClient;
??memset(&addrClient, 0, sizeof(SOCKADDR_IN));
??sClient = accept(pDlg->m_svrSocket, (PSOCKADDR)&addrClient, &iAddress);
??????? if (INVALID_SOCKET == sClient)
??????? {
??//?AfxMessageBox("delete pClient");
???pDlg->PostMessage(WM_ACCEPT_CLOSE, 0, 0);
??????????? break;
??????? }
??????? else
??????? {
???pDlg->PostMessage(WM_NEW_CLIENT, (WPARAM)sClient, (LPARAM)lParam);
??//?char szRecvMsg[256] = {0};
??//?char szOutMsg[256] = {0};
???//接收客戶端內(nèi)容:阻塞
??//?sClient.Receive(szRecvMsg, 256);
??//?sprintf(szOutMsg, "Receive Msg: %s? ", szRecvMsg);
??//?AfxMessageBox("");
??//?pDlg->GetDlgItemText(IDC_EDIT_LOG, strText);
??//?strText += szOutMsg;
???//aDlg->SetDlgItemText(IDC_EDIT_LOG, strText);
???//發(fā)送內(nèi)容給客戶端
??//?serverSocket.Send("Have Receive The Msg", 50);
???//關(guān)閉
??//?sClient.Close();
??//?serverSocket.Close();
??????? }
?}
?return -1;
}
void CXEIM_ChatroomDlg::ShowAndUpdate()
{
?PostMessage(XM_EMDBLCLICKTREE);
}
void CXEIM_ChatroomDlg::XDoubleClickUserList(WPARAM wParam, LPARAM lParam)
{
?ShowWindow(SW_SHOW);
?GetDlgItem(IDC_RICHEDIT2)->SetFocus();
}
總結(jié)
以上是生活随笔為你收集整理的C++写的一个聊天室代码,用于XEIM开源即时通讯软件上的的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qt Creator和VS2010中添加
- 下一篇: Qt修炼手册1_溢美之词和Designe