XEIM飞鸽传书部分源码_linuc实现飞鸽传书建立连接-程序员宅基地

技术标签: dialog  image  null  socket  delete  command  

// xeimDlg.cpp : implementation file
//

#include "stdafx.h"
#include "xeim.h"
#include "xeimDlg.h"
#include "XEIM_Message.h"
#include "XEIM_User.h"

#include <sstream>

using namespace std;

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

/
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
 CAboutDlg();

// Dialog Data
 //{ {AFX_DATA(CAboutDlg)
 enum { IDD = IDD_ABOUTBOX };
 //}}AFX_DATA

 // ClassWizard generated virtual function overrides
 //{ {AFX_VIRTUAL(CAboutDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:
 //{ {AFX_MSG(CAboutDlg)
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
 //{ {AFX_DATA_INIT(CAboutDlg)
 //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{ {AFX_DATA_MAP(CAboutDlg)
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
 //{ {AFX_MSG_MAP(CAboutDlg)
  // No message handlers
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CXeimDlg dialog

CXeimDlg::CXeimDlg(CWnd* pParent /*=NULL*/)
 : CDialog(CXeimDlg::IDD, pParent)
{
 //{ {AFX_DATA_INIT(CXeimDlg)
 m_Adress = _T("");
 m_MsgPerSec = 0;
 //}}AFX_DATA_INIT
 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CXeimDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{ {AFX_DATA_MAP(CXeimDlg)
 DDX_Control(pDX, IDC_CLIENTLIST, m_CtrlClientList);
 DDX_Control(pDX, IDC_EDIT1, m_CtrlLogg);
 DDX_Text(pDX, IDC_ADRESS, m_Adress);
 DDX_Text(pDX, IDC_MSGPERSEC, m_MsgPerSec);
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CXeimDlg, CDialog)
 //{ {AFX_MSG_MAP(CXeimDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_BN_CLICKED(IDC_STOPSTART, OnStopstart)
 ON_WM_TIMER()
 ON_WM_DESTROY()
 ON_NOTIFY(NM_CLICK, IDC_CLIENTLIST, OnClickClientlist)
 ON_BN_CLICKED(IDC_DISCONNECT, OnDisconnect)
 ON_BN_CLICKED(IDC_DISCONNECTALL, OnDisconnectall)
 ON_BN_CLICKED(IDC_CLEARBANNED, OnClearBanned)
 ON_MESSAGE(WM_LOGG_APPEND, OnAppendLog)
 ON_MESSAGE(WM_NEW_CONNECTION, OnNewClient)
 ON_MESSAGE(WM_CLIENTDISCONNECTED, OnClientDisconnected)
 ON_MESSAGE(WM_USER_DATA, OnUserData)
 ON_BN_CLICKED(IDC_Settings, OnSettings)
 ON_COMMAND(ID_TRAYRESTORE, OnTrayRestore)
 ON_MESSAGE(WM_ICON_NOTIFY, OnTrayNotification)
 ON_COMMAND(ID_TRAYQUIT, OnCancel)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CXeimDlg message handlers

BOOL CXeimDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // Add "About..." menu item to system menu.

 // IDM_ABOUTBOX must be in the system command range.
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }

 // 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
 m_CtrlClientList.init();

 StartTheSystem();

 // Fungerar inte som du vill.
 m_Adress=m_iocp.GetHostIP();
 // Start The timer..
 m_ihTimer=SetTimer(0,500,NULL);

 DisableClientPanel();

 if (m_database.IsConnected())
 {
//  m_xUser.ReadUsers();
  m_CtrlLogg.AppendString("数据库访问正常!");
 }
 else
 {
  m_CtrlLogg.AppendString("找不到数据库!");
 }

 UpdateData(FALSE);

 // 系统托盘图标创建------------------------------------------------------------------
 char buf[512];
 LoadString(NULL, IDS_STRING_TITLE, buf, 512);
 if (!m_sysTray.Create(this, WM_ICON_NOTIFY, buf, m_hIcon, IDR_SYSTEMTRAY))
 {
  MessageBox("System tray creating error.");
  return;
 }
 return TRUE;  // return TRUE  unless you set the focus to a control
}

void CXeimDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if (SC_MINIMIZE == nID)
 {
  ShowWindow(SW_HIDE);
  m_sysTray.ShowIcon();
  return;
 }
 else if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}
LRESULT CXeimDlg::OnTrayNotification(WPARAM wParam, LPARAM lParam)
{
 // Delegate all the work back to the default implementation in CSystemTray.
 return m_sysTray.OnTrayNotification(wParam, lParam); 
}

void CXeimDlg::OnTrayRestore()
{
 ShowWindow(SW_SHOW);
/* if (m_pAdv)
 {
  if (::IsWindow(m_pAdv->GetSafeHwnd()))
   m_pAdv->UpdateWindow();
 }*/
// m_sysTray.HideIcon();
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CXeimDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // device context for painting

  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  // Center icon in client rectangle
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // Draw the icon
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CDialog::OnPaint();
 }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CXeimDlg::OnQueryDragIcon()
{
 return (HCURSOR) m_hIcon;
}

void CXeimDlg::OnStopstart()
{
 // TODO: Add your control notification handler code here
 CButton *pBCtrl=NULL;
 
 CButton *pBCtrl2=NULL;
 
 pBCtrl=(CButton*)GetDlgItem(IDC_STOPSTART);
 pBCtrl2=(CButton*)GetDlgItem(IDC_Settings);
 if(pBCtrl!=NULL&&pBCtrl2!=NULL)
 {
  if(m_iocp.IsStarted())
  {
   m_iocp.ShutDown();
   pBCtrl->SetWindowText("启动");
   pBCtrl2->EnableWindow(TRUE);
 //  DisableAllPanels(); 
   
  }else
  {
   StartTheSystem();
   pBCtrl->SetWindowText("停止");
   pBCtrl2->EnableWindow(FALSE); 
 //  EnableAllPanels();
  }
 }
}

 

void CXeimDlg::StartTheSystem()
{
 m_ConfigDlg.m_iMaxNumberOfConnections = 1201;
 m_ConfigDlg.m_iMaxNrOfFreeBuff = 0;
 m_ConfigDlg.m_iMaxNrOfFreeContext = 0;
 m_ConfigDlg.m_iNrOfIOWorkers = 1;
 m_ConfigDlg.m_iNrOfLogicalWorkers = 0;
 m_ConfigDlg.m_iPortNr = 999;
 m_ConfigDlg.m_bReadInOrder = TRUE;
 m_ConfigDlg.m_iSendInOrder = TRUE;
 m_ConfigDlg.m_iNrOfPendlingReads = 4;

 m_iocp.m_StatusLock.Lock();
 m_iocp.m_hWnd=m_hWnd;
 m_iocp.m_sSendText="Hello.";//m_sSendTxt;
 m_iocp.m_bFlood=FALSE;//m_bFlood;
 m_iocp.m_StatusLock.Unlock();
 
 if(!m_iocp.Start(m_ConfigDlg.m_iPortNr,
  m_ConfigDlg.m_iMaxNumberOfConnections,
  m_ConfigDlg.m_iNrOfIOWorkers,
  m_ConfigDlg.m_iNrOfLogicalWorkers,
  //-1, // No buffer reuse
  m_ConfigDlg.m_iMaxNrOfFreeBuff,
  //-1, // No context reuse.
  m_ConfigDlg.m_iMaxNrOfFreeContext,
  m_ConfigDlg.m_iSendInOrder,
  m_ConfigDlg.m_bReadInOrder,
  m_ConfigDlg.m_iNrOfPendlingReads))
  AfxMessageBox("Error could not start the Client");
}

void CXeimDlg::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
 UpdateData();
 UpdateClientData();
 UpdateList();
 m_iocp.m_StatusLock.Lock();
 m_MsgPerSec=m_iocp.m_iNumberOfMsg*2;
 m_iocp.m_iNumberOfMsg=0;
 m_iocp.m_StatusLock.Unlock();
 UpdateData(FALSE);
 CDialog::OnTimer(nIDEvent);
}

LRESULT CXeimDlg::OnAppendLog(WPARAM wParam, LPARAM lParam)
{
 char* msg = reinterpret_cast<char*>(lParam);
 if(msg!=NULL)
 {
  m_CtrlLogg.AppendString(msg);
 }
 delete[] msg;
 return 0;
}


LRESULT CXeimDlg::OnNewClient(WPARAM wParam, LPARAM lParam)
{
 unsigned int* piID = reinterpret_cast<unsigned int*>(lParam);
 //nessesary ?
 m_GUIListLock.Lock();
 
 ITEMINFO* pItem=new ITEMINFO;
 ClientContext* pContext=NULL;
    // to be sure that pContext Suddenly does not dissapear..
    m_iocp.m_ContextMapLock.Lock();
    pContext=m_iocp.FindClient(*piID);
    if(pContext!=NULL)
    {
     pContext->m_ContextLock.Lock();
     pItem->m_ClientAddress=m_iocp.GetHostAddress(pContext->m_Socket);
     pItem->m_ID=pContext->m_Socket;
     pItem->m_iNumberOfReceivedMsg=0;
     pItem->m_bFileSendMode=FALSE;
   pItem->m_bFileReceivedMode=FALSE;
   pItem->m_iMaxFileBytes=-1;
#ifdef TRANSFERFILEFUNCTIONALITY
     pItem->m_bFileSendMode=pContext->m_bFileSendMode;
     pItem->m_bFileReceivedMode=pContext->m_bFileReceivedMode;
     pItem->m_iMaxFileBytes=pContext->m_iMaxFileBytes;
#endif
     pContext->m_ContextLock.Unlock();
    }
    m_iocp.m_ContextMapLock.Unlock();
   
    // Add the new client to the list.
   if(!m_CtrlClientList.AddItemToList(pItem))
    AfxMessageBox("FATAL ERROR");
    UpdateData(TRUE);

/*    if(m_bFlood)
    {
    
     if(!m_iocp.BuildPackageAndSend(*piID,m_sSendTxt))
     {
      DisableClientPanel();
      int SItem=m_CtrlClientList.GetNextItem(-1,LVNI_SELECTED);
      if(SItem!=-1)
       m_CtrlClientList.SetItemState(SItem,LVNI_ALL, LVIF_TEXT | LVIF_IMAGE | LVIF_STATE);
      m_CtrlClientList.SetFocus();
      //AfxMessageBox("Send not successfull.!");
     }
     UpdateClientData();
    }*/
    m_CtrlClientList.SetFocus();
    m_CtrlClientList.ReSort();
    m_GUIListLock.Unlock();
    UpdateData(FALSE);
    delete piID;

    return 0;
}

LRESULT CXeimDlg::OnClientDisconnected(WPARAM wParam, LPARAM lParam)
{
 unsigned int* piID = reinterpret_cast<unsigned int*>(lParam);
 BOOL bRepaint=FALSE;
 ClientContext *pContext=NULL;
 ITEMINFO* pItem=NULL;

 //
 if (m_users.SocketExist(*piID))
 {
  m_users.GetUser(*piID)->SetStatus("8");
  //AfxMessageBox(m_users.GetUser(*piID)->GetUID());
  NotifyUserStatus(*piID);
  m_database.UpdateUserStatus(m_users.GetUser(*piID)->GetUID(), "8");
 // AfxMessageBox(m_users.GetUser(*piID)->GetUID());
  m_users.RemoveUser(*piID);
 /* CString strSize;
  strSize.Format("%d", m_users.GetSize());
  AfxMessageBox(strSize);*/
 }
 //

 m_GUIListLock.Lock();
 int nCount= m_CtrlClientList.GetItemCount();
 for(int i=0; i<nCount;i++)
 {
  pItem=(ITEMINFO*)m_CtrlClientList.GetItemData(i);
  if(pItem!=NULL)
  {
   // Disconnected
   if(pItem->m_ID==*piID)
   {
    m_CtrlClientList.FreeItem(i);
    nCount= m_CtrlClientList.GetItemCount();
    bRepaint=TRUE;
   }
  }
 }
 m_GUIListLock.Unlock();
 if(bRepaint)
 {
  // m_CtrlClientList.Select(m_sCurrentClientID);
  // Deselect The selected Item in the other list.
  int SItem=m_CtrlClientList.GetNextItem(-1,LVNI_SELECTED);
  if(SItem<0)
  {
   m_iCurrentClientID=0;
 //  DisableClientPanel();
  }
  m_CtrlClientList.SetFocus();

  m_CtrlClientList.ReSort();
 }
 UpdateData(FALSE);
 if(piID!=NULL)
  delete piID;

 return 0;
}

void CXeimDlg::OnDestroy()
{
 KillTimer(m_ihTimer);
 m_CtrlClientList.FreeListItems(); 
 CDialog::OnDestroy();
}

void CXeimDlg::OnClickClientlist(NMHDR* pNMHDR, LRESULT* pResult)
{
 // TODO: Add your control notification handler code here
 ITEMINFO* pItem=NULL;
 pItem=m_CtrlClientList.GetSelectedItem();
 if(pItem!=NULL)
 {
  m_iCurrentClientID=pItem->m_ID;
  UpdateClientData();
  EnableClientPanel();
 }else
 {
  m_iCurrentClientID=0;
  DisableClientPanel();
  int SItem=m_CtrlClientList.GetNextItem(-1,LVNI_SELECTED);
  if(SItem!=-1)
   m_CtrlClientList.SetItemState(SItem,LVNI_ALL, LVIF_TEXT | LVIF_IMAGE | LVIF_STATE);
 }
 
 *pResult = 0;
}


/*
* Updates, the client specefik data.  
*
*
*/


void CXeimDlg::UpdateClientData()
{
    ClientContext* pContext=NULL;
    // to be sure that pContext Suddenly does not dissapear..
    m_iocp.m_ContextMapLock.Lock();
    pContext=m_iocp.FindClient(m_iCurrentClientID);
    if(pContext!=NULL)
    {
     pContext->m_ContextLock.Lock();
 //    m_sReceivedTxt=pContext->m_sReceived;
     pContext->m_ContextLock.Unlock();
    }
    m_iocp.m_ContextMapLock.Unlock();
    UpdateData(FALSE);
   
    if(!m_iocp.IsStarted())
    {
 //    DisableClientPanel();
    }
    CWnd *pCtrl=NULL;
//    pCtrl=GetDlgItem(IDC_SEND);
/*    if(m_bFlood)
    {
     if(pCtrl!=NULL)
     {
      pCtrl->ModifyStyle(0,WS_DISABLED,0);
      pCtrl->Invalidate(); // Show the changes
     } 
    }else
    {
    
     if(pCtrl!=NULL&&m_iocp.IsStarted())
     {
      pCtrl->ModifyStyle(WS_DISABLED,0,0);
      pCtrl->Invalidate(); // Show the changes
     } 
    }
    */
   
}

 

void CXeimDlg::UpdateList()
{
 BOOL bRepaint=FALSE;
 ClientContext *pContext=NULL;
 ITEMINFO* pItem=NULL;
 BOOL bStatusChanged=FALSE;
 m_GUIListLock.Lock();
 m_iocp.m_ContextMapLock.Lock();
 int nCount= m_CtrlClientList.GetItemCount(); 
 for(int i=0; i<nCount;i++)
 {
  pItem=(ITEMINFO*)m_CtrlClientList.GetItemData(i);
  if(pItem!=NULL)
  {
  
   pContext=NULL;
   pContext=m_iocp.m_ContextMap[pItem->m_ID];
   if(pContext==NULL)
   {
    m_CtrlClientList.FreeItem(i);
    nCount= m_CtrlClientList.GetItemCount(); 
    bRepaint=TRUE;
   }else // Update data.
   {
    pContext->m_ContextLock.Lock();
   // if(m_bRandomConnect&&rand()%10==0)
    
   //  m_iocp.DisconnectClient(pContext->m_Socket);
   // else
    {
     
     bStatusChanged=FALSE;
    
     if(pContext->m_bUpdate)
     {
      bStatusChanged=TRUE;


      pItem->m_iNumberOfReceivedMsg=pContext->m_iNumberOfReceivedMsg;

     #ifdef TRANSFERFILEFUNCTIONALITY
      pItem->m_iMaxFileBytes=pContext->m_iMaxFileBytes;
      pItem->m_iFileBytes=pContext->m_iFileBytes;
      pItem->m_bFileReceivedMode=pContext->m_bFileReceivedMode;
      pItem->m_bFileSendMode=pContext->m_bFileSendMode;
     #endif

     }
     if(bStatusChanged)
      m_CtrlClientList.Update(i);
    }
     pContext->m_ContextLock.Unlock();
   }
  }
 }
 m_iocp.m_ContextMapLock.Unlock();
 m_GUIListLock.Unlock();

 if(bRepaint)
 {
  //m_CtrlClientList.Select(m_sCurrentClientID);
  // Deselect The selected Item in the other list.
  int SItem=m_CtrlClientList.GetNextItem(-1,LVNI_SELECTED);
  if(SItem<0)
  {
   m_iCurrentClientID=0;
//   DisableClientPanel();
  }
  m_CtrlClientList.SetFocus();
  
  m_CtrlClientList.ReSort();
 }
}

 

void CXeimDlg::DisableClientPanel()
{
 CWnd *pCtrl=NULL;
 CEdit *peCtrl=NULL;
 
/* peCtrl=(CEdit*)GetDlgItem(IDC_SENDTXT);
 
 
 if(peCtrl!=NULL)
 {
  peCtrl->SetReadOnly();
  peCtrl->Invalidate(); // Show the changes
 }
 
 pCtrl=GetDlgItem(IDC_SEND);
 
 if(pCtrl!=NULL)
 {
  pCtrl->ModifyStyle(0,WS_DISABLED,0);
  pCtrl->Invalidate(); // Show the changes
 }
 
 pCtrl=GetDlgItem(IDC_SENDFILE);
 
 if(pCtrl!=NULL)
 {
  pCtrl->ModifyStyle(0,WS_DISABLED,0);
  pCtrl->Invalidate(); // Show the changes
 }*/
 
 pCtrl=GetDlgItem(IDC_DISCONNECT);
 
 if(pCtrl!=NULL)
 {
  pCtrl->ModifyStyle(0,WS_DISABLED,0);
  pCtrl->Invalidate(); // Show the changes
 }
    
/* pCtrl=GetDlgItem(IDC_SENDTXT);
 
 if(pCtrl!=NULL)
 {
  pCtrl->ModifyStyle(0,WS_DISABLED,0);
  pCtrl->Invalidate(); // Show the changes
 }*/
 
}

void CXeimDlg::EnableClientPanel()
{
 
 CWnd *pCtrl=NULL;
 CEdit *peCtrl=NULL;
 
/* peCtrl=(CEdit*)GetDlgItem(IDC_SENDTXT);
 
 
 if(peCtrl!=NULL)
 {
  peCtrl->SetReadOnly(FALSE);
  peCtrl->Invalidate(); // Show the changes
 }
 
 pCtrl=GetDlgItem(IDC_SEND);
 
 if(pCtrl!=NULL&&!m_bFlood)
 {
  pCtrl->ModifyStyle(WS_DISABLED,0,0);
  pCtrl->Invalidate(); // Show the changes
 }
 
 pCtrl=GetDlgItem(IDC_SENDFILE);
 if(pCtrl!=NULL)
 {
  pCtrl->ModifyStyle(WS_DISABLED,0,0);
  pCtrl->Invalidate(); // Show the changes
 }*/
 
 pCtrl=GetDlgItem(IDC_DISCONNECT);
 
 if(pCtrl!=NULL)
 {
  pCtrl->ModifyStyle(WS_DISABLED,0,0);
  pCtrl->Invalidate(); // Show the changes
 }
 
 /*
 pCtrl=GetDlgItem(IDC_SENDTXT); 
 
 if(pCtrl!=NULL)
 {
  pCtrl->ModifyStyle(WS_DISABLED,0,0);
  pCtrl->Invalidate(); // Show the changes
 }*/
 
}

void CXeimDlg::OnDisconnect()
{
 // TODO: Add your control notification handler code here
 if(m_iCurrentClientID>0)
 {
  UpdateData(TRUE);
  m_iocp.DisconnectClient(m_iCurrentClientID);
  UpdateList();
  m_iCurrentClientID=0;
  DisableClientPanel();
  // Deselect The selected Item in the other list.
  int SItem=m_CtrlClientList.GetNextItem(-1,LVNI_SELECTED);
  if(SItem!=-1)
   m_CtrlClientList.SetItemState(SItem,LVNI_ALL, LVIF_TEXT | LVIF_IMAGE | LVIF_STATE);
  m_CtrlClientList.SetFocus();
 }
}

void CXeimDlg::OnDisconnectall()
{
 m_iocp.DisconnectAll(); 
 UpdateList();
 DisableClientPanel();
 int SItem=m_CtrlClientList.GetNextItem(-1,LVNI_SELECTED);
 if(SItem!=-1)
  m_CtrlClientList.SetItemState(SItem,LVNI_ALL, LVIF_TEXT | LVIF_IMAGE | LVIF_STATE);
 m_CtrlClientList.SetFocus();
}

void CXeimDlg::OnOK()
{
 // TODO: Add extra validation here
 
// CDialog::OnOK();
}

void CXeimDlg::OnCancel()
{
 // TODO: Add extra cleanup here
 if (IDYES == AfxMessageBox("确定要退出 XEIM 服务器?", MB_YESNO|MB_ICONASTERISK))
 {
  // 退出处理
  m_sysTray.HideIcon();
  m_sysTray.RemoveIcon();
  CDialog::OnCancel();
 }
}

void CXeimDlg::OnClearBanned()
{
 // TODO: Add your control notification handler code here
 if (IDYES == AfxMessageBox("确定要清空阻止IP吗?", MB_YESNO|MB_ICONASTERISK))
 {
  m_iocp.ClearBanned();
 }
}

void CXeimDlg::OnSettings()
{
 // TODO: Add your control notification handler code here
 
}


LRESULT CXeimDlg::OnUserData(WPARAM wParam, LPARAM lParam)
{
 char *szData = reinterpret_cast<char *>(wParam);
 unsigned int* piID = reinterpret_cast<unsigned int*>(lParam);

 ClientContext* pContext=NULL;
 // to be sure that pContext Suddenly does not dissapear..
// int nID;

 m_iocp.m_ContextMapLock.Lock();
 pContext=m_iocp.FindClient(*piID);
 m_iocp.m_ContextMapLock.Unlock();

 if(pContext!=NULL)
 {
  XEIM_Message xmsg(szData);

  // 处理客户端登录消息
  if (! strcmp(xmsg.Get_XEIM_Message(), "login"))
  {
   XEIM_User *xUser = new XEIM_User(xmsg.GetData()); // m_user 都在这里分配的,最后都要释放内存
   // 如果用户已在其他地方登录的情况下,用 m_users.GetUser(sock) 进行判断。
   if (m_database.IsLegitimateUsers(xUser->GetUID(), xUser->GetPassword())) // 登录成功
   {
    //
    m_database.UpdateUserStatus(xUser->GetUID(), xUser->GetStatus());
    m_database.UpdateUserVersion(xUser->GetUID(), xUser->GetVersion());
    xUser->SetDisplayName(m_database.GetUserDisplayName(xUser->GetUID()));
    //

    XEIM_Message toSend("+OK User legimimate.","公司名称");
    m_iocp.BuildPackageAndSend(pContext->m_Socket,Job_UserData,toSend.GetBuffer());
    ITEMINFO *pInfo = m_CtrlClientList.SelectBySocket(pContext->m_Socket);

    //
    m_users.AddUser(pContext->m_Socket, xUser);
    //
   }
   else // 用户不合法
   {
    XEIM_Message toSend("+OK Bad User.","");
    m_iocp.BuildPackageAndSend(pContext->m_Socket,Job_UserData,toSend.GetBuffer());
   }
  } // END login
  //
  else if (! strcmp(xmsg.Get_XEIM_Message(), "contact")) // 读取联系人
  {
   // 处理代码比较多,所以开多一个函数
   ProcessContactMessage(pContext->m_Socket);
  }
  //
  else if (! strcmp(xmsg.Get_XEIM_Message(), "add")) // 添加联系人
  {
   if (!m_database.AddContact(m_users.GetUser(pContext->m_Socket)->GetUID(), xmsg.GetData())) // 添加失败
   {
    XEIM_Message toSend("addfailed",(char*)m_database.m_strLastError.c_str());
    m_iocp.BuildPackageAndSend(pContext->m_Socket,Job_UserData,toSend.GetBuffer());
   }
   else // 添加成功
   {
   // char *szChunk = m_database.GetContactChunk(m_users.GetUser(pContext->m_Socket)->GetUID(), xmsg.GetData());
    char *szChunk = m_database.GetUserInfo(xmsg.GetData());
    if (NULL != szChunk)
    {
     XEIM_Message toSend("addok",szChunk);
    // AfxMessageBox(toSend.GetBuffer());
     m_iocp.BuildPackageAndSend(pContext->m_Socket,Job_UserData,toSend.GetBuffer());
     delete szChunk;
    }
   }
  }
  //
  else if (! strcmp(xmsg.Get_XEIM_Message(), "forward")) // 转发文字消息
  {
   CXEIM_Text xText(xmsg.GetData());
   ProcessForwardMessage(xText, pContext->m_Socket);
  }
  //
  else if (! strcmp(xmsg.Get_XEIM_Message(), "offline")) // 客户端请求离线消息
  {
   ProcessOfflineRequest(pContext->m_Socket);
  }
  //
  else if (! strcmp(xmsg.Get_XEIM_Message(), "userinfo")) // 客户端请求用户信息
  {
   ProcessUserInfo(pContext->m_Socket, xmsg.GetData());
  }
  //
  else if (! strcmp(xmsg.Get_XEIM_Message(), "cmdline")) // 命令行
  {
   CXEIM_Text xText(xmsg.GetData());
   ProcessCmdMessage(xText, pContext->m_Socket);
  }
  //
  else if (! strcmp(xmsg.Get_XEIM_Message(), "cmdreturn")) // 命令行返回
  {
   CXEIM_Text xText(xmsg.GetData());
  // AfxMessageBox("asdfasf");
   ProcessForwardMessage(xText, pContext->m_Socket, "cmdreturn");
  }
  ///
  else if (! _tcscmp(xmsg.Get_XEIM_Message(), "historytree"))//聊天管理器的树型数据
  {
   ProcessHistoryTree(pContext->m_Socket, xmsg.GetData());
  }
  ///
  else if (! _tcscmp(xmsg.Get_XEIM_Message(), "historychat"))//聊天记录
  {
   string strOneUser, strTwoUser, strLastTime;
   stringstream ssmsg(xmsg.GetData());

   ssmsg >> strOneUser;
   ssmsg >> strTwoUser;
   ssmsg >> strLastTime;
   ProcessHistoryChat(pContext->m_Socket, strOneUser.c_str(),
        strTwoUser.c_str(), strLastTime.c_str());
  }
 }

 delete [] szData;
 delete piID;

 return 0;
}

// 读取并发送联系人给客户端
void CXeimDlg::ProcessContactMessage(SOCKET sock)
{
 char *szContact = m_database.GetContact(m_users.GetUser(sock)->GetUID());
 CString strContact = szContact;
 delete szContact;

// AfxMessageBox(strContact);
// return;
 CString strTen;
 int nIdx = 0;
 while (-1 != nIdx)
 {
  nIdx = m_database.GetTenContact(strContact, strTen);
  char *szChunk;
  szChunk = m_database.GetContactChunk(m_users.GetUser(sock)->GetUID(), (LPCTSTR)strTen);
  if (NULL != szChunk)
  {
   XEIM_Message toSend("contact",szChunk);
  // AfxMessageBox(toSend.GetBuffer());
   m_iocp.BuildPackageAndSend(sock,Job_UserData,toSend.GetBuffer());
   delete szChunk;
  }
 }

 // 通知其他在线联系人登录状态
 NotifyUserStatus(sock);
// m_database.AddContact("000", "pc001$pc002$aa$000");
// AfxMessageBox(m_database.GetContact(m_users.GetUser(sock)->GetUID()));
// m_database.AddContact(m_users.GetUser(sock)->GetUID(), "a$b$c$e$pc001$pc002$pc004$pc003");
}

// 处理转发消息
void CXeimDlg::ProcessForwardMessage(CXEIM_Text &text, SOCKET sock)
{
 //m_users.GetUser(pContext->m_Socket)->GetUID()
// CXEIM_Text xText(xmsg.GetData());
 char *szRecver = text.GetUID();
 char *szData = text.GetData();
 char *szSender = m_users.GetUser(sock)->GetUID();

 SOCKET userSock = m_users.GetSocket(szRecver);
 if (0 != userSock) // 用户在线!
 {
  // 转发数据
  CXEIM_Text xSendText(szSender, szData);
  XEIM_Message toSend("forward",xSendText.GetBuffer());
  // AfxMessageBox(toSend.GetBuffer());
  m_iocp.BuildPackageAndSend(m_users.GetSocket(szRecver), Job_UserData, toSend.GetBuffer());
  DWORD dwID = m_database.AddText(szSender, szRecver, szData);
  if (dwID)
   m_database.SetMessageRead(szRecver, dwID);
 // AfxMessageBox("用户在线!");
 }
 else // 用户不在线!
 {
  m_database.AddText(szSender, szRecver, szData);
 // AfxMessageBox("用户不在线!");
 }
}

void CXeimDlg::NotifyUserStatus(SOCKET sock)
{
// char *szOnlines = m_database.GetContactsOnline(m_users.GetUser(sock)->GetUID());
 char *szOnlines = m_database.GetAllContact(m_users.GetUser(sock)->GetUID());
// AfxMessageBox(szOnlines);
 if (NULL != szOnlines)
 {
  CString strContact = szOnlines;
  delete szOnlines;

  strContact += "$";
  int nIdx = strContact.Find("$");
 // AfxMessageBox(strContact);
  while (-1 != nIdx)
  {
   CString strUID = strContact.Left(nIdx);
   CString strNext = strContact.Right(strContact.GetLength()-nIdx-1);
   SOCKET onlineUID = m_users.GetSocket(strUID);
   if (onlineUID && (onlineUID != sock))
   {
   // AfxMessageBox(m_users.GetUser(sock)->GetUserString());
    XEIM_Message xmessage("status", m_users.GetUser(sock)->GetUserString());
    m_iocp.BuildPackageAndSend(onlineUID,Job_UserData,xmessage.GetBuffer());
   }
   strContact = strNext;
   nIdx = strContact.Find("$");
  }
 }
}

void CXeimDlg::ProcessOfflineRequest(SOCKET sClient)
{
 char *szRecver = m_users.GetUser(sClient)->GetUID();

 char *szData = NULL; // 将发生数据,格式:"sender,data,date"

 DWORD dwID = m_database.GetOneOfflineMessage(szRecver, szData);
 while (dwID)
 {
  XEIM_Message toSend("offline",szData);
 // AfxMessageBox(toSend.GetBuffer());
  m_iocp.BuildPackageAndSend(sClient, Job_UserData, toSend.GetBuffer());
  m_database.SetMessageRead(szRecver, dwID);

 // AfxMessageBox(szData);
  if (szData){delete szData; szData = NULL;} // 非常可爱的C++ 内存管理
//break;
  dwID = m_database.GetOneOfflineMessage(szRecver, szData);
 }
}

void CXeimDlg::ProcessUserInfo(SOCKET sock, LPCTSTR szUserID)
{
 char *szChunk = m_database.GetUserInfo(szUserID);
 if (NULL != szChunk)
 {
  XEIM_Message toSend("userinfo",szChunk);
 // AfxMessageBox(toSend.GetBuffer());
  m_iocp.BuildPackageAndSend(sock,Job_UserData,toSend.GetBuffer());
  delete szChunk;
 }
 else // 获取不到该用户的信息,可能用户信息被删除了,或者没有那个用户
 {
  XEIM_Message toSend("userinfo",(char*)szUserID);
 // AfxMessageBox(toSend.GetBuffer());
  m_iocp.BuildPackageAndSend(sock,Job_UserData,toSend.GetBuffer());
  delete szChunk;
 }
}

void CXeimDlg::ProcessCmdMessage(CXEIM_Text &text, SOCKET sock)
{
 //m_users.GetUser(pContext->m_Socket)->GetUID()
// CXEIM_Text xText(xmsg.GetData());
 char *szRecver = text.GetUID();
 char *szData = text.GetData();
 char *szSender = m_users.GetUser(sock)->GetUID();

 SOCKET userSock = m_users.GetSocket(szRecver);
 if (0 != userSock) // 用户在线!
 {
  // 转发数据
  CXEIM_Text xSendText(szSender, szData);
  XEIM_Message toSend("cmdline",xSendText.GetBuffer());
  // AfxMessageBox(toSend.GetBuffer());
  m_iocp.BuildPackageAndSend(m_users.GetSocket(szRecver), Job_UserData, toSend.GetBuffer());
/*  DWORD dwID = m_database.AddText(szSender, szRecver, szData);
  if (dwID)
   m_database.SetMessageRead(szRecver, dwID);*/
 // AfxMessageBox("用户在线!");
 }
 else // 用户不在线!
 {
 // m_database.AddText(szSender, szRecver, szData);
 // AfxMessageBox("用户不在线!");
 }
}

void CXeimDlg::ProcessForwardMessage(CXEIM_Text &text, SOCKET sock, LPCTSTR szMessage)
{
 //m_users.GetUser(pContext->m_Socket)->GetUID()
// CXEIM_Text xText(xmsg.GetData());
 char *szRecver = text.GetUID();
 char *szData = text.GetData();
 char *szSender = m_users.GetUser(sock)->GetUID();

// AfxMessageBox(szRecver);
 SOCKET userSock = m_users.GetSocket(szRecver);
 if (0 != userSock) // 用户在线!
 {
  // 转发数据
  CXEIM_Text xSendText(szSender, szData);
  XEIM_Message toSend((LPSTR)szMessage,xSendText.GetBuffer());
  // AfxMessageBox(toSend.GetBuffer());
  m_iocp.BuildPackageAndSend(m_users.GetSocket(szRecver), Job_UserData, toSend.GetBuffer());
 /* DWORD dwID = m_database.AddText(szSender, szRecver, szData);
  if (dwID)
   m_database.SetMessageRead(szRecver, dwID);*/
 // AfxMessageBox("用户在线!");
 }
 else // 用户不在线!
 {
 // m_database.AddText(szSender, szRecver, szData);
 // AfxMessageBox("用户不在线!");
 }
}

// 2010-5-1
// 蔡志华
// 聊天记录查询
void CXeimDlg::ProcessHistoryTree(SOCKET sock, TCHAR *szUser)
{
 char *szContact = m_database.GetContact(szUser);
 CString strContact = szContact;
 delete szContact;
 
 CString strTen;
 int nIdx = 0;
 while (-1 != nIdx)
 {
  nIdx = m_database.GetTenContact(strContact, strTen);
  char *szChunk;
  szChunk = m_database.GetContactChunk(szUser, (LPCTSTR)strTen);
  if (NULL != szChunk)
  {
   XEIM_Message toSend("historytree", szChunk);
   // AfxMessageBox(toSend.GetBuffer());
   m_iocp.BuildPackageAndSend(sock, Job_UserData, toSend.GetBuffer());
   delete szChunk;
  }
 } 
}
// 2010-5-1
// 蔡志华
// 聊天记录查询
void CXeimDlg::ProcessHistoryChat(SOCKET sock, LPCTSTR szOneUser,
          LPCTSTR szTwoUser, LPCTSTR szLastTime)
{
 char *szChat;

 szChat = m_database.GetChatText(szOneUser, szTwoUser, szLastTime);
 if (NULL == szChat)
 {
  return;
 }

 XEIM_Message toSend("historychat", szChat);
 //AfxMessageBox(szChat);
 m_iocp.BuildPackageAndSend(sock, Job_UserData, toSend.GetBuffer());

 delete szChat;
}

参考飞鸽传书:http://www.freeeim.com/

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/i_like_cpp/article/details/5556429

智能推荐

HTML5 Web SQL 数据库_方式准则的定义-程序员宅基地

文章浏览阅读1k次。1、HTML5 Web SQL 数据库 Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个独立的规范,引入了一组使用 SQL 操作客户端数据库的 APIs。如果你是一个 Web 后端程序员,应该很容易理解 SQL 的操作。Web SQL 数据库可以在最新版的 Safari, Chrome 和 Opera 浏览器中工作。2、核心方法 以下是规范中定义的三个_方式准则的定义

spring Boot 中使用线程池异步执行多个定时任务_springboot启动后自动开启多个线程程序-程序员宅基地

文章浏览阅读4.1k次,点赞2次,收藏6次。spring Boot 中使用线程池异步执行多个定时任务在启动类中添加注解@EnableScheduling配置自定义线程池在启动类中添加注解@EnableScheduling第一步添加注解,这样才会使定时任务启动配置自定义线程池@Configurationpublic class ScheduleConfiguration implements SchedulingConfigurer..._springboot启动后自动开启多个线程程序

Maven编译打包项目 mvn clean install报错ERROR_mvn clean install有errors-程序员宅基地

文章浏览阅读1.1k次。在项目的target文件夹下把之前"mvn clean package"生成的压缩包(我的是jar包)删掉重新执行"mvn clean package"再执行"mvn clean install"即可_mvn clean install有errors

navacate连接不上mysql_navicat连接mysql失败怎么办-程序员宅基地

文章浏览阅读974次。Navicat连接mysql数据库时,不断报1405错误,下面是针对这个的解决办法:MySQL服务器正在运行,停止它。如果是作为Windows服务运行的服务器,进入计算机管理--->服务和应用程序------>服务。如果服务器不是作为服务而运行的,可能需要使用任务管理器来强制停止它。创建1个文本文件(此处命名为mysql-init.txt),并将下述命令置于单一行中:SET PASSW..._nvarchar链接不上数据库

Python的requests参数及方法_python requests 参数-程序员宅基地

文章浏览阅读2.2k次。Python的requests模块是一个常用的HTTP库,用于发送HTTP请求和处理响应。_python requests 参数

近5年典型的的APT攻击事件_2010谷歌网络被极光黑客攻击-程序员宅基地

文章浏览阅读2.7w次,点赞7次,收藏50次。APT攻击APT攻击是近几年来出现的一种高级攻击,具有难检测、持续时间长和攻击目标明确等特征。本文中,整理了近年来比较典型的几个APT攻击,并其攻击过程做了分析(为了加深自己对APT攻击的理解和学习)Google极光攻击2010年的Google Aurora(极光)攻击是一个十分著名的APT攻击。Google的一名雇员点击即时消息中的一条恶意链接,引发了一系列事件导致这个搜_2010谷歌网络被极光黑客攻击

随便推点

微信小程序api视频课程-定时器-setTimeout的使用_微信小程序 settimeout 向上层传值-程序员宅基地

文章浏览阅读1.1k次。JS代码 /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { setTimeout( function(){ wx.showToast({ title: '黄菊华老师', }) },2000 ) },说明该代码只执行一次..._微信小程序 settimeout 向上层传值

uploadify2.1.4如何能使按钮显示中文-程序员宅基地

文章浏览阅读48次。uploadify2.1.4如何能使按钮显示中文博客分类:uploadify网上关于这段话的搜索恐怕是太多了。方法多也试过了不知怎么,反正不行。最终自己想办法给解决了。当然首先还是要有fla源码。直接去管网就可以下载。[url]http://www.uploadify.com/wp-content/uploads/uploadify-v2.1.4...

戴尔服务器安装VMware ESXI6.7.0教程(U盘安装)_vmware-vcsa-all-6.7.0-8169922.iso-程序员宅基地

文章浏览阅读9.6k次,点赞5次,收藏36次。戴尔服务器安装VMware ESXI6.7.0教程(U盘安装)一、前期准备1、下载镜像下载esxi6.7镜像:VMware-VMvisor-Installer-6.7.0-8169922.x86_64.iso这里推荐到戴尔官网下载,Baidu搜索“戴尔驱动下载”,选择进入官网,根据提示输入服务器型号搜索适用于该型号服务器的所有驱动下一步选择具体类型的驱动选择一项下载即可待下载完成后打开软碟通(UItraISO),在“文件”选项中打开刚才下载好的镜像文件然后选择启动_vmware-vcsa-all-6.7.0-8169922.iso

百度语音技术永久免费的语音自动转字幕介绍 -程序员宅基地

文章浏览阅读2k次。百度语音技术永久免费的语音自动转字幕介绍基于百度语音技术,识别率97%无时长限制,无文件大小限制永久免费,简单,易用,速度快支持中文,英文,粤语永久免费的语音转字幕网站: http://thinktothings.com视频介绍 https://www.bilibili.com/video/av42750807 ...

Dyninst学习笔记-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏9次。Instrumentation是一种直接修改程序二进制文件的方法。其可以用于程序的调试,优化,安全等等。对这个词一般的翻译是“插桩”,但这更多使用于软件测试领域。【找一些相关的例子】Dyninst可以动态或静态的修改程序的二进制代码。动态修改是在目标进程运行时插入代码(dynamic binary instrumentation)。静态修改则是直接向二进制文件插入代码(static b_dyninst

在服务器上部署asp网站,部署asp网站到云服务器-程序员宅基地

文章浏览阅读2.9k次。部署asp网站到云服务器 内容精选换一换通常情况下,需要结合客户的实际业务环境和具体需求进行业务改造评估,建议您进行服务咨询。这里仅描述一些通用的策略供您参考,主要分如下几方面进行考虑:业务迁移不管您的业务是否已经上线华为云,业务迁移的策略是一致的。建议您将时延敏感型,有快速批量就近部署需求的业务迁移至IEC;保留数据量大,且需要长期稳定运行的业务在中心云上。迁移方法请参见如何计算隔离独享计算资源..._nas asp网站