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

智能推荐

小程序开发者工具正常显示,但是真机调试和真机中安卓加载正常ios加载首页失败,首页的请求返回204_苹果 sec-fetch-dest-程序员宅基地

文章浏览阅读125次。检查请求头中的’sec-fetch-dest’: ‘document’ ,是否进行了特殊处理(node层)_苹果 sec-fetch-dest

ansible 批量安装zabbix-agent-程序员宅基地

文章浏览阅读321次。服务器初始化(这是在建立在新的服务器基础上做的初始化)关闭防火墙、selinux,添加epel常用源,安装常用工具、添加普通用户并禁止root1、服务器批量初始化[root@fwd ansible]# cat init.yml 系统初始化脚本---- hosts: all tasks: - name: disable selinux、firew..._ansible批量安装zabbix-agent

java日志系统--log4j配置解析过程,源码分析_log4j 源码分析 读取配置-程序员宅基地

文章浏览阅读1.4w次,点赞3次,收藏2次。Logger.getLogger(Test.class);从getLogger开始,就启动了log4j的整个工作流程,通过调用LogManager获取logger实例return LogManager.getLogger(clazz.getName());LogManager类里面有个静态块static{},【初始化重要信息】【root logger】,做一些配置,其中url = Loader.ge_log4j 源码分析 读取配置

心灵震撼《一个8岁女孩的遗书》看完能有几人不哭…-程序员宅基地

文章浏览阅读533次。无奈的父亲­有一个美丽的小女孩,她的名字叫余艳,她有一双亮晶晶的大眼睛她有一颗透明的童心.她是一个孤儿,她在这个世界上只活了8年,她留在这个世界上最后的一句话是“我来过,我很乖”她希望死在秋天,纤瘦的身体就像一朵花自然开谢的过程.在遍地黄花堆积,落叶空中旋舞的时候,她会看见横空远行的雁儿们.她自愿放弃治疗,把全世界华人捐给她的54万分成了7份,把生命当成希望的蛋糕分给了7个正徘徊在生死线上的小

C++音视频开发从放弃到入门 (基于FFmpeg+OpenCV)-程序员宅基地

文章浏览阅读1.1w次,点赞12次,收藏88次。音视频开发一定要学C++吗?答案是肯定的。虽然其它语言也能搞音视频开发,甚至使用起来更简单,但“语言越高级,离真相就越远”,当你的功能需求日益增多,程序的性能需求越来越迫切,你想进一步了解程序实现的细节时,使用其它语言往往会面临“无法解决”的困境,最后不得不使用C++来解决问题,我们何不从一开始就使用C++呢?FFmpeg及OpenCV是开源、跨平台的音视频开发SDK,搞音视频开发基本都需要用到它。_c++音视频开发

C# 爬虫 100个明星贴吧_如何用爬虫爬取百度贴吧的贴吧c#-程序员宅基地

文章浏览阅读2.8k次。每个吧 第一页 using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Net;using System.Text;using System.Text.RegularExpressions;namespace ConsoleApplication8{_如何用爬虫爬取百度贴吧的贴吧c#

随便推点

EV/HEV中的牵引逆变器驱动优化-程序员宅基地

文章浏览阅读1.6k次,点赞42次,收藏35次。什么是牵引逆变器?从本质上讲,牵引逆变器是电动汽车动力系统中的一个子系统,它从电池中获取高电压,并将其转换为交流电压——因此被称为逆变器——并基本上为电机供电。它控制电机速度和扭矩,直接影响效率和可靠性,这正成为牵引逆变器设计的设计挑战。此图片来源于网络如今的电动汽车至少有一个牵引逆变器。有些型号实际上不止一个。一个在前轴上,一个在后轴上。甚至一些高端车型实际上每个车轮都有一个牵引逆变器。因此,效率和可靠性非常重要。所以,从逆变器和电机控制的市场趋势来看——从技术趋势来看,我们看到了功率水平的提高。

Ubuntu之apt命令_ubuntu18.04 atp命令使用技巧-程序员宅基地

文章浏览阅读134次。简介apt-cache和apt-get是apt包的管理工具,他们根据/etc/apt/sources.list里的软件源地址列表搜索目标软件、并通过维护本地软件包列表来安装和卸载软件。查看本机是否安装软件:whereis package_name 或者which package_name1.搜索软件sudo apt-cache search pa..._ubuntu18.04 atp命令使用技巧

查询Dynamics 365的Audit History_dynamics 审核历史记录如何查询-程序员宅基地

文章浏览阅读150次。【代码】查询Dynamics 365的Audit History。_dynamics 审核历史记录如何查询

python yield函数的用法-程序员宅基地

文章浏览阅读1.3w次,点赞15次,收藏66次。什么是yield函数?yield函数是python里面的关键字,带有yield的函数相当于一个生成器generator.当你使用一个yield的时候,对应的函数就是一个生成器在python里面类似于return函数,他们主要的区别就是:遇到return会直接返回值,不会执行接下来的语句.但是yield并不是,在本次迭代返回之后,yield函数在下一次迭代时,从上一次迭代遇到的yield后面的代码(下一行)开始执行下面是案例分析:案例一:def gen_generator(): yiel_yield函数

【QT笔记】QFile读文件问题_qfileread后指针会移动吗-程序员宅基地

文章浏览阅读917次。如果不用seek(0)的话,默认是自己会把读取文件的指针后移的,不用手动后移;_qfileread后指针会移动吗

dw8051基本测试示例_dw8051 part1-程序员宅基地

文章浏览阅读2.5k次。整理了网上一份简单的dw8051测试示例,共享到云盘:http://pan.baidu.com/s/1bnu9lZT1.目录如下:---dut ---rtl:DW8051的core文件 ---model:ROM和RAM的model文件---testbench ---rtl.f:filelist文件 ---test_top.v:仿真的top_dw8051 part1