VC下基于消息机制的UDP连接实现

1. 声明变量

/*****************    http://blog.csdn.net/elysium    *************************/

/**************************    MainFrm.H    **********************************/

public:
    HICON m_hIcon;
 BOOL CreateAlarmSocket();
 SOCKET m_sockAlarm;
 UINT m_nAlarmPort;
 CString m_strAlarmAddr;
 struct sockaddr_in m_srvaddrAlarm, m_sockaddrinAlarm; 

...

afx_msg LRESULT OnReceiveAlarmSock(WPARAM wParam, LPARAM lParam);

2. 基本步骤

在项目头文件UDPDemo.H声明变量

#define WM_ALARMSOCK  WM_USER + 200

 TCHAR m_szDataSource[255];    //服务器计算机名称或文件DSN -- Name of server machine or local cube file
 TCHAR m_szCatalog[255];     //数据源名称 -- Name of default (initial) database (catalog)
 TCHAR m_szUserID[255];     //用户名称
 TCHAR m_szPassword[255];     //用户密码

 TCHAR m_szAlarmAddr[255];     //报警Socket地址
 TCHAR m_szCallAddr[255];     //语音Socket地址

BOOL CUDPDemoApp::InitInstance()
{
  ...
 if (!AfxSocketInit())
 {
  MessageBox(NULL, "初始化SOCKET服务失败", "UdpDemo", MB_ICONEXCLAMATION | MB_OK);
  return FALSE;
 }
...
}
 
int CUDPDemoApp::ExitInstance()
{
    WriteConfig();                          //保存配置文件信息
 CoUninitialize( );                      //关闭COM组件库,释放COM资源
    if (m_hOnlyMutex)
        CloseHandle(m_hOnlyMutex);
 return CWinApp::ExitInstance();
}
 
//读取INI文件
BOOL CUDPDemoApp::ReadConfig()
{
 TCHAR exeFullPath[MAX_PATH];
 CString strIniFile;
 //GetModuleFileNameEx(NULL, exeFullPath, MAX_PATH); // Exists in PSAPI.H
 ::GetModuleFileName(NULL, exeFullPath, MAX_PATH);
 
 strIniFile.Format("%s", exeFullPath);
 exeFullPath[strIniFile.GetLength()-18] = '/0';
 strIniFile.Format("%s", exeFullPath);
 strIniFile += INIFILENAME; //"Config.INI";
 try
 {
  ::GetPrivateProfileString("DATABASE", "DataSource", LOCALHOST, m_szDataSource, MAX_PATH, strIniFile);
  ::GetPrivateProfileString("DATABASE", "Catalog", LOCALHOST, m_szCatalog, MAX_PATH, strIniFile);
  ::GetPrivateProfileString("DATABASE", "UserID", LOCALHOST, m_szUserID, MAX_PATH, strIniFile);
  ::GetPrivateProfileString("DATABASE", "Password", LOCALHOST, m_szPassword, MAX_PATH, strIniFile);
  
  ::GetPrivateProfileString("SOCKET", "AlarmRemoteHost", "127.0.0.1", m_szAlarmAddr, 16, strIniFile);
  m_uiAlarmPort = ::GetPrivateProfileInt("SOCKET", "AlarmPort", 5001, strIniFile);

 }
 catch (CException *e)
 {
  e->ReportError();
  e->Delete();
  return FALSE;
 }
 return TRUE;
}
//配置INI文件
BOOL CUDPDemoApp::WriteConfig()
{
 TCHAR exeFullPath[MAX_PATH];
 CString strIniFile;
 //GetModuleFileNameEx(NULL, exeFullPath, MAX_PATH); // Exists in PSAPI.H
 ::GetModuleFileName(NULL, exeFullPath, MAX_PATH);
 
 strIniFile.Format("%s", exeFullPath);
 exeFullPath[strIniFile.GetLength()-18] = '/0';
 strIniFile.Format("%s", exeFullPath);
 strIniFile += INIFILENAME; //"Config.INI";
 try
 {
  ::WritePrivateProfileString("DATABASE", "DataSource", m_szDataSource, strIniFile);
  ::WritePrivateProfileString("DATABASE", "Catalog", m_szCatalog, strIniFile);
  ::WritePrivateProfileString("DATABASE", "UserID", m_szUserID, strIniFile);
  ::WritePrivateProfileString("DATABASE", "Password", m_szPassword, strIniFile);
  
  ::WritePrivateProfileString("SOCKET", "AlarmRemoteHost", m_szAlarmAddr, strIniFile);
        itoa(m_uiAlarmPort, strAlarmPort, 10);
  ::WritePrivateProfileString("SOCKET", "AlarmPort", strAlarmPort, strIniFile);
 }
 catch (CException *e)
 {
  e->ReportError();
  e->Delete();
  return FALSE;
 }
 return TRUE;
}
 
/*********    MainFrm.CPP    **********/
ON_MESSAGE(WM_ALARMSOCK, OnReceiveAlarmSock)
 
//建立报警Socket
BOOL CMainFrame::CreateAlarmSocket()
{
 WORD wVersionRequested = MAKEWORD(2, 2); //采用WinSock2.2版本
 WSADATA WSAData = {0};
 int err;
 err = WSAStartup(wVersionRequested, &WSAData);
 if (0 != err)
 {
  MessageBox(_T("没有发现可用的 WinSock DLL"), _T("UdpDemo"), MB_ICONINFORMATION | MB_OK);
  return FALSE;
 }

 if (LOBYTE(WSAData.wVersion) != LOBYTE(wVersionRequested) ||
  HIBYTE(WSAData.wVersion) != HIBYTE(wVersionRequested))
 {
  MessageBox(_T("Winsock.dll 版本不匹配"), _T("UdpDemo -- http://blog.csdn.net/elysium"), MB_ICONINFORMATION | MB_OK);
  
  WSACleanup();
  return FALSE;
 }
 m_sockAlarm = socket(AF_INET, SOCK_DGRAM, 0);
 if (INVALID_SOCKET == m_sockAlarm)
 {
  CString strError;
  strError.Format("%d: Socket创建失败",  WSAGetLastError());
  AfxMessageBox(strError, MB_OK);
  closesocket(m_sockAlarm);
  return FALSE;
 }
 m_sockaddrinAlarm.sin_family = AF_INET;
 m_sockaddrinAlarm.sin_addr.s_addr = INADDR_ANY; //inet_addr(m_strAlarmAddr);//INADDR_ANY;
 m_sockaddrinAlarm.sin_port = htons(m_nAlarmPort);//htons(0); 
 if(SOCKET_ERROR ==(bind(m_sockAlarm, (SOCKADDR*)&m_sockaddrinAlarm, sizeof(m_sockaddrinAlarm/*SOCKADDR*/))))
 {
  AfxMessageBox(_T("绑定失败-报警Socket"), MB_ICONINFORMATION + MB_OK);
  return FALSE;
 }
 m_srvaddrAlarm.sin_family = AF_INET;
 m_srvaddrAlarm.sin_addr.s_addr = inet_addr(m_strAlarmAddr);
 m_srvaddrAlarm.sin_port =  htons(m_nAlarmPort);
 //if (SOCKET_ERROR == (m_sockAlarm.Connect((LPSOCKADDR)&m_srvaddrAlarm, sizeof(m_srvaddrAlarm))))
 //{
 // AfxMessageBox("Windows Sockets Error", MB_OK);
 // return FALSE;
 //}
 /*
 CMainFrame* pMainFrame = new CMainFrame;
 pMainFrame->LoadFrame(IDR_MENU_DISPATCH);
 if (pMainFrame->m_hWnd == AfxGetMainWnd()->m_hWnd)
 {
  AfxMessageBox("OK");
 }
 */
 //WSAAsyncSelect(m_sockAlarm, this->GetSafeHwnd(), WM_ALARMSOCK, FD_READ);
 //CMainFrame* pMainFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
 //WSAAsyncSelect(m_sockAlarm, pMainFrame->m_hWnd, WM_ALARMSOCK, FD_READ);
 WSAAsyncSelect(m_sockAlarm, this->m_hWnd, WM_ALARMSOCK, FD_READ);
 m_srvaddrAlarm.sin_family = AF_INET;
 m_srvaddrAlarm.sin_addr.s_addr = inet_addr(m_strAlarmAddr);
 m_srvaddrAlarm.sin_port =  htons(m_nAlarmPort);
 return TRUE;
}
//接收处理报警
LRESULT CMainFrame::OnReceiveAlarmSock(WPARAM wParam, LPARAM lParam)
{
 char Buffer[4096];
 int len;
 int flen = sizeof(m_srvaddrAlarm);
 CString value;
 CString strType="报警", strDate, strTime, strSource, strSort, strEvent, strUser="中心";
 m_srvaddrAlarm.sin_port = htons(m_nAlarmPort);
 
 CUdpDemoListView* m_pListView = (CUdpDemoListView*)m_wndSplitter.GetPane(1, 0);
 CListCtrl* m_pListCtrl = (CListCtrl*)&m_pListView->GetListCtrl();
 int nIndex = 0;
 switch (WSAGETSELECTEVENT(lParam))
 {
 case FD_READ:
  {
  len = recvfrom(m_sockAlarm, Buffer, sizeof(Buffer), 0, (LPSOCKADDR)&m_srvaddrAlarm, &flen);
  value = Buffer; 
  nIndex = value.Find(',', 0); //严格来说,还需处理字符特殊情况,如连着逗号,空格等:,,  ,1,......
  if (nIndex > 0)
  {
   strDate = value.Left(value.Find(' ', 0));
   strTime = value.Mid(value.Find(' ', 0)+1, nIndex-1-value.Find(' ', 0));
   value.Delete(0, nIndex+1);
  }
  nIndex = value.Find(',', 0);
  if (nIndex > 0)
  {
   strSource = value.Left(nIndex);
   value.Delete(0, nIndex+1);
  }
  nIndex = value.Find(',', 0);
  if (nIndex > 0)
  {
   strSort = value.Left(nIndex);
   value.Delete(0, nIndex+1);
  }
  nIndex = value.Find(',', 0);
  if (nIndex > 0)
  {
   //strSource = value.Left(nIndex) + "/t" + strSource;
   value.Delete(0, nIndex+1);
  }
  nIndex = value.GetLength();
  if (nIndex > 0)
  {
   strEvent = value;
  }
 
  int nRow = m_pListCtrl->GetItemCount();
  m_pListCtrl->InsertItem(nRow, strType, 0);
  m_pListCtrl->SetItemText(nRow, 1, strDate);
  m_pListCtrl->SetItemText(nRow, 2, strTime);
  m_pListCtrl->SetItemText(nRow, 3, strSource);
  m_pListCtrl->SetItemText(nRow, 4, strSort);
  m_pListCtrl->SetItemText(nRow, 5, strEvent);
  m_pListCtrl->SetItemText(nRow, 6, strUser);
  m_pListCtrl->EnsureVisible(nRow, TRUE);
 
  }
  // dispose value;
  break;
 default:;
 }

 return 0L;
}
//同步报警(报警菜单ON_COMMAND命令)
void CMainFrame::OnSysAlarm()
{
 m_bAlarm = !m_bAlarm;
 if (m_bAlarm)
 {
  m_bAlarm = CreateAlarmSocket();
  if (!m_bAlarm)
  {
   closesocket(m_sockAlarm);
  }
 }
 else
 {
  closesocket(m_sockAlarm);
 }
}
 
//报警菜单ON_UPDATE_UI命令
void CMainFrame::OnUpdateSysAlarm(CCmdUI* pCmdUI)
{
 pCmdUI->SetCheck(m_bAlarm);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值