【MFC实战项目】No.2 网络调试助手

您所在的位置:网站首页 miui125网络助手 【MFC实战项目】No.2 网络调试助手

【MFC实战项目】No.2 网络调试助手

2024-06-10 18:48| 来源: 网络整理| 查看: 265

                                                   前  言

基于MFC对话框开发了一款网络调试助手,只实现了TCP,还未实现UDP。某些功能与前面开发的串口调试助手原理相同,这里就不打算再做了。

VS版本:

Microsoft Visual Studio 2008 9.0.30729.1 SP

                                                  目  录

1.  软件成果展示

2.  源代码

(1)头文件  NetAssistDlg.h

(2)源文件 NetAssistDlg.cpp

3.  说明

4.   项目下载地址

                                            1.  软件成果展示

  这里同样使用铭心软体工作室出品的网络调试助手(V 3.7)进行测试。接着开软件分TCP服务器和TCP客户端进行测试。项目下载地址附文末。

 

                                                  2.  源代码 (1)头文件  NetAssistDlg.h // NetAssistDlg.h : 头文件 // #pragma once #include "afxwin.h" #include "afxcmn.h" #include #include using namespace std; // CNetAssistDlg 对话框 class CNetAssistDlg : public CDialog { // 构造 public: CNetAssistDlg(CWnd* pParent = NULL); // 标准构造函数 // 对话框数据 enum { IDD = IDD_NETASSIST_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: HICON m_hIcon; // 生成的消息映射函数 virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() /* ==================== function ======================= */ public: void InitMenu(); // 初始化菜单栏 void InitNetSetting(); // 初始化网络设置 void SetNetSetCtrlEnable(BOOL Enable = TRUE); // 设置网络设置控件是否可编辑 void ResizeRecvCtrl(BOOL bSmall = FALSE); // 设置网络数据接收区控件大小 void SetSerCtrlAreaVisable(BOOL bVisable = FALSE); // 隐藏与显示控件 void SetCliCtrlAreaVisable(BOOL bVisable = FALSE); // 隐藏与显示控件 void SetConectState(BOOL bConnect = FALSE); // 设置连接状态 void SetRecvNum(); // 接收字节数 void SetSendNum(); // 发送字节数 /* 连接/断开连接 */ void UDPConOrDis(); // UDP void TCPSerConOrDis(); // TCP Server BOOL CheckPortIsOccupy(DWORD dwPort); // 检测TCP端口是否被占用 void TCPCliConOrDis(); // TCP Client CString GetIPAddr(CIPAddressCtrl *ipCtrl); // 获取界面上的IP地址 DWORD GetPort(CEdit *edtCtrl); // 获取界面上的端口号 void SetRecvData(CString strData); // 设置接收区内容 /* 发送消息 */ void SendDataUdp(char *pszData); // UDP发送数据 void SendDataTcpServer(char *pszData); // TCP Server发送数据 void SendDataTcpClient(char *pszData); // TCP CLient发送数据 UINT findSocketInVector(SOCKET newSocket); // 容器中查找端口号 LRESULT OnShowTask(WPARAM wParam, LPARAM lParam); // 托盘图标显示 public: CMenu m_Menu; int m_nRecvCount; int m_nSendCount; BOOL m_bConnect; // 套接字 CServerSocket m_server; CClientSocket m_client; vector m_VecSocket; // 保存客户端套接字 public: CComboBox m_cmb_proToCol; // 协议类型 CIPAddressCtrl m_ipa_lochostIP; // 本地IP地址/服务器IP地址 CStatic m_pic_flag; // 连接/未连接状态标识图片控件 CEdit m_edt_locHostPort; // 本地端口/服务器端口 CButton m_btn_conDis; // 连接/断开连接按钮 CStatic m_edt_connectState; // 状态栏连接/未连接标识 CStatic m_edt_sendNum; // 状态栏发送字节数 CStatic m_edt_recvNum; // 状态栏接收字节数 CEdit m_edt_recvData; // 网络数据接收 CEdit m_edt_sendData; // 发送区 CButton m_ckb_send3; // 发送完自动清空 CButton m_ckb_recv2; // 自动换行显示 CStatic m_stc_localIP; // 本地IP CStatic m_stc_localPort; // 本地端口 CStatic m_stc_tarHost; // 目标地址 CStatic m_stc_tarPort; // 目标端口 CIPAddressCtrl m_ipa_tarHostIP; // 目标IP地址 CEdit m_edt_tarPort; // 目标端口 CStatic m_gpb_recvData; // 网络数据接收 CStatic m_stc_conTar; // 连接对象 CComboBox m_cmb_conTar; // 连接对象 CStatic m_stc_newCon; // 状态栏 客户端连接/断开 public: afx_msg void OnBnClickedBtnClearnum(); // 状态栏复位按钮 afx_msg void OnBnClickedBtnClrecv(); // 接受区清除显示 afx_msg void OnBnClickedBtnClsend(); // 清除输入 afx_msg void OnBnClickedBtnCondis(); // 连接/断开连接 afx_msg void OnCbnSelchangeCmbProtocol(); // 协议类型改变 afx_msg void OnClose(); // 窗口关闭响应函数 afx_msg void OnBnClickedBtnSenddata(); // 发送数据 afx_msg void OnMenuAboutBtnClicked(); // 菜单栏关于按钮 afx_msg void OnMenuexitbtn(); // 菜单栏退出按钮 };

 

(2)源文件 NetAssistDlg.cpp // NetAssistDlg.cpp : 实现文件 // #include "stdafx.h" #include "NetAssist.h" #include "NetAssistDlg.h" #include "Iphlpapi.h" #include #include "Winsock2.h" #include #pragma comment(lib, "Iphlpapi.lib") #pragma comment(lib, "ws2_32.lib") #ifdef _DEBUG #define new DEBUG_NEW #endif NOTIFYICONDATA g_Tray; // 托盘图标全局变量 CString g_strAddrAndPort; // 套接字回调函数 // 服务器端 void SNewSocketCallBack(const SOCKADDR_IN *szSockAddr, SOCKET newSocket, void *pUserParam); // 客户端连接 void SNewMsgCallBack(const SOCKADDR_IN *pSockAddr, const SOCKET_HAND *pSocketHand, const SOCKET_DATA *pData, void *pUserParam); // 接收消息 void SCloseSocketCallBack(const char *szSocket, SOCKET newSocket, void *pUserParam); // 客户端断开连接 // 客户端 void CNewMsgCallBack(long nPort, SOCKET svrSocket, const SOCKET_DATA *pData, void *pUserParam); // 接收消息 void CDisconnetCallBack(void *pUsr); // 服务器断开连接 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialog { public: CAboutDlg(); // 对话框数据 enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() // CNetAssistDlg 对话框 CNetAssistDlg::CNetAssistDlg(CWnd* pParent /*=NULL*/) : CDialog(CNetAssistDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CNetAssistDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_CMB_PROTOCOL, m_cmb_proToCol); DDX_Control(pDX, IDC_IPA_LOCALHOSTIP, m_ipa_lochostIP); DDX_Control(pDX, IDC_STC_ICO, m_pic_flag); DDX_Control(pDX, IDC_EDT_LOCALHOSTPOR, m_edt_locHostPort); DDX_Control(pDX, IDC_BTN_CONDIS, m_btn_conDis); DDX_Control(pDX, IDC_STC_STATE, m_edt_connectState); DDX_Control(pDX, IDC_STC_SENDNUM, m_edt_sendNum); DDX_Control(pDX, IDC_STC_RECVNUM, m_edt_recvNum); DDX_Control(pDX, IDC_EDT_RECVDATA, m_edt_recvData); DDX_Control(pDX, IDC_EDT_SENDDATA, m_edt_sendData); DDX_Control(pDX, IDC_CK_SEND3, m_ckb_send3); DDX_Control(pDX, IDC_CK_RECV2, m_ckb_recv2); DDX_Control(pDX, IDC_STC_LOACLHOSTIP, m_stc_localIP); DDX_Control(pDX, IDC_STC_LOCALHOSTPOR, m_stc_localPort); DDX_Control(pDX, IDC_STC_TARHOST, m_stc_tarHost); DDX_Control(pDX, IDC_STC_TARPORT, m_stc_tarPort); DDX_Control(pDX, IDC_IPA_TARHOST, m_ipa_tarHostIP); DDX_Control(pDX, IDC_EDT_TARPORT, m_edt_tarPort); DDX_Control(pDX, IDC_STATIC_SERAILDATARECV, m_gpb_recvData); DDX_Control(pDX, IDC_EDT_TARPORT, m_edt_tarPort); DDX_Control(pDX, IDC_STC_CONTAR, m_stc_conTar); DDX_Control(pDX, IDC_CMB_CONTAR, m_cmb_conTar); DDX_Control(pDX, IDC_STC_NEWCONECT, m_stc_newCon); } BEGIN_MESSAGE_MAP(CNetAssistDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_BN_CLICKED(IDC_BTN_CLEARNUM, &CNetAssistDlg::OnBnClickedBtnClearnum) ON_BN_CLICKED(IDC_BTN_CLRECV, &CNetAssistDlg::OnBnClickedBtnClrecv) ON_BN_CLICKED(IDC_BTN_CLSEND, &CNetAssistDlg::OnBnClickedBtnClsend) ON_BN_CLICKED(IDC_BTN_CONDIS, &CNetAssistDlg::OnBnClickedBtnCondis) ON_CBN_SELCHANGE(IDC_CMB_PROTOCOL, &CNetAssistDlg::OnCbnSelchangeCmbProtocol) ON_WM_CLOSE() ON_BN_CLICKED(IDC_BTN_SENDDATA, &CNetAssistDlg::OnBnClickedBtnSenddata) ON_COMMAND(ID_32773, &CNetAssistDlg::OnMenuAboutBtnClicked) ON_MESSAGE(WM_SHOWTASK, &CNetAssistDlg::OnShowTask) // 托盘图标 ON_COMMAND(ID_MenuExitBtn, &CNetAssistDlg::OnMenuexitbtn) END_MESSAGE_MAP() // CNetAssistDlg 消息处理程序 LRESULT CNetAssistDlg::OnShowTask(WPARAM wParam, LPARAM lParam) { if (wParam != IDR_MAINFRAME) return 1; if (lParam == WM_LBUTTONDBLCLK) // 左键点击托盘 { this->ShowWindow(SW_SHOWNORMAL); this->SetForegroundWindow(); Shell_NotifyIcon(NIM_DELETE, &g_Tray); } if (lParam == WM_RBUTTONDBLCLK) // 右键点击 { // 右键弹出托盘菜单 CMenu menu; menu.LoadMenu(IDR_MENU1); CMenu *pPopUp = menu.GetSubMenu(0); CPoint pt; GetCursorPos(&pt); SetForegroundWindow(); pPopUp->TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this); PostMessage(WM_NULL, 0, 0); } return 0; } BOOL CNetAssistDlg::OnInitDialog() { CDialog::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 /************************************************************************/ /* */ /************************************************************************/ this->InitMenu(); this->InitNetSetting(); this->SetConectState(FALSE); m_ckb_recv2.SetCheck(TRUE); m_nSendCount = 0; m_nRecvCount = 0; m_bConnect = FALSE; // 设置套接字回调函数 m_server.m_pUserParam = this; m_server.NewSocketCallBack = SNewSocketCallBack; m_server.NewMsgCallBack = SNewMsgCallBack; m_server.CloseSocketCallBack = SCloseSocketCallBack; m_client.m_pUserParam = this; m_client.NewMsgCallBack = CNewMsgCallBack; m_client.DisconnetCall = CDisconnetCallBack; ResizeRecvCtrl(FALSE); SetSerCtrlAreaVisable(FALSE); SetCliCtrlAreaVisable(FALSE); m_cmb_conTar.AddString(_T("All Connections")); m_cmb_conTar.SetCurSel(0); /************************************************************************/ /* */ /************************************************************************/ return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } void CNetAssistDlg::OnSysCommand(UINT nID, LPARAM lParam) { if (nID == SC_MINIMIZE) // 最小化窗口 { g_Tray.cbSize = (DWORD)sizeof(NOTIFYICONDATA); g_Tray.hWnd = this->m_hWnd; g_Tray.uID = IDR_MAINFRAME; g_Tray.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; g_Tray.uCallbackMessage = WM_SHOWTASK; // 自定义的消息名称 g_Tray.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME)); lstrcpy(g_Tray.szTip, _T("网络调试助手 V1.0")); // 信息提示条 Shell_NotifyIcon(NIM_ADD, &g_Tray); // 在托盘区添加图标 ShowWindow(SW_HIDE); // 隐藏主窗口 return; } if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CNetAssistDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 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; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR CNetAssistDlg::OnQueryDragIcon() { return static_cast(m_hIcon); } /************************************************************************/ /* */ /************************************************************************/ // 加载菜单项 void CNetAssistDlg::InitMenu() { m_Menu.LoadMenu( IDR_MENU1 ); this->SetMenu(&m_Menu); } void CNetAssistDlg::InitNetSetting() { // 协议类型 m_cmb_proToCol.AddString(_T("UDP")); m_cmb_proToCol.AddString(_T("TCP Server")); m_cmb_proToCol.AddString(_T("TCP Client")); m_cmb_proToCol.SetCurSel(0); // 本地IP地址 char *pszLocIp = m_server.GetLocalIP(); if (pszLocIp = "0.0.0.0") pszLocIp = "127.0.0.1"; m_ipa_lochostIP.SetWindowText(pszLocIp); // 本地端口号 m_edt_locHostPort.SetWindowText(_T("8080")); } // 设置网络设置控件是否可编辑 void CNetAssistDlg::SetNetSetCtrlEnable(BOOL Enable) { m_cmb_proToCol.EnableWindow(Enable); m_ipa_lochostIP.EnableWindow(Enable); m_edt_locHostPort.EnableWindow(Enable); } void CNetAssistDlg::ResizeRecvCtrl(BOOL bSmall) { // 获取消息接收区控件在窗口客户区的坐标及大小 CRect rectGpb, rectEdt; m_gpb_recvData.GetWindowRect(&rectGpb); m_edt_recvData.GetWindowRect(&rectEdt); ScreenToClient(&rectGpb); ScreenToClient(&rectEdt); rectGpb.bottom = bSmall ? 425 : 495; rectEdt.bottom = bSmall ? 420 : 490; m_gpb_recvData.MoveWindow(&rectGpb); m_edt_recvData.MoveWindow(&rectEdt); } void CNetAssistDlg::SetSerCtrlAreaVisable(BOOL bVisable) { m_stc_conTar.ShowWindow(bVisable); m_cmb_conTar.ShowWindow(bVisable); } void CNetAssistDlg::SetCliCtrlAreaVisable(BOOL bVisable) { m_stc_tarHost.ShowWindow(bVisable); m_stc_tarPort.ShowWindow(bVisable); m_ipa_tarHostIP.ShowWindow(bVisable); m_edt_tarPort.ShowWindow(bVisable); if ( bVisable ) { char *pszLocIp = m_server.GetLocalIP(); if (pszLocIp = "0.0.0.0") pszLocIp = "127.0.0.1"; m_ipa_tarHostIP.SetWindowText(pszLocIp); } } // 设置连接/断开图片标识,连接/断开按钮,状态栏连接状态 void CNetAssistDlg::SetConectState(BOOL bConnect) { HICON hIcon; CString strBtn, strEdt; if ( bConnect ) { hIcon = AfxGetApp()->LoadIcon( IDI_ICN_CONNECT ); strBtn = _T("断开"); strEdt = _T("已连接"); } else { hIcon = AfxGetApp()->LoadIcon( IDI_ICN_DISCON ); strBtn = _T("连接"); strEdt = _T("未连接"); } m_pic_flag.SetIcon(hIcon); m_btn_conDis.SetWindowText(strBtn); m_edt_connectState.SetWindowText(_T("连接状态:") + strEdt); } // 接收字节数 void CNetAssistDlg::SetRecvNum() { CString strRecvNum; strRecvNum.Format("%d", m_nRecvCount); m_edt_recvNum.SetWindowText(_T("接收:") + strRecvNum); } // 发送字节数 void CNetAssistDlg::SetSendNum() { CString strSendNum; strSendNum.Format("%d", m_nSendCount); m_edt_sendNum.SetWindowText(_T("发送:") + strSendNum); } // 复位计数 void CNetAssistDlg::OnBnClickedBtnClearnum() { m_nRecvCount = 0; m_nSendCount = 0; SetRecvNum(); SetSendNum(); } // 清除显示 void CNetAssistDlg::OnBnClickedBtnClrecv() { m_edt_recvData.SetWindowText(_T("")); } // 清除输入 void CNetAssistDlg::OnBnClickedBtnClsend() { m_edt_sendData.SetWindowText(_T("")); } // 协议类型改变 void CNetAssistDlg::OnCbnSelchangeCmbProtocol() { CString strLocalIP; CString strLocalPort; // TCP Client if (m_cmb_proToCol.GetCurSel() == 2) { strLocalIP = _T("(2)服务器IP地址"); strLocalPort = _T("(3)服务器端口"); } else { strLocalIP = _T("(2)本地IP地址"); strLocalPort = _T("(3)本地端口号"); } m_stc_localIP.SetWindowText(strLocalIP); m_stc_localPort.SetWindowText(strLocalPort); } /************************************************************************/ /* 连接/断开连接 */ /************************************************************************/ // 连接/断开 void CNetAssistDlg::OnBnClickedBtnCondis() { switch (m_cmb_proToCol.GetCurSel()) { case 0: //UDP UDPConOrDis(); break; case 1: // TCP Server TCPSerConOrDis(); break; case 2: // TCP Client TCPCliConOrDis(); break; default: break; } } // UDP void CNetAssistDlg::UDPConOrDis() { m_stc_tarHost.SetWindowText(_T("目标主机:")); m_stc_tarPort.SetWindowText(_T("目标端口:")); return; } // TCP Server void CNetAssistDlg::TCPSerConOrDis() { // 已连接的情况下,断开连接 if ( m_bConnect ) { if ( m_server.StopListening() ) // 停止监听 { SetRecvData(_T("服务器已断开连接!\r\n")); m_bConnect = FALSE; SetConectState(FALSE); m_cmb_conTar.ResetContent(); m_cmb_conTar.AddString(_T("All Connections")); m_cmb_conTar.SetCurSel(0); SetNetSetCtrlEnable(TRUE); ResizeRecvCtrl(FALSE); SetSerCtrlAreaVisable(FALSE); } else { SetRecvData(_T("服务器断开连接错误!\r\n")); } return; }// if (m_bConnect) // 未连接的情况下,连接 if ( !m_bConnect ) { DWORD dwPort = GetPort(&m_edt_locHostPort); // 检测端口是否被占用 if ( CheckPortIsOccupy(dwPort) ) { SetRecvData(_T("创建服务器失败,端口已被其它应用程序占用!\r\n")); return; } if ( m_server.StartListening(dwPort, TCP_TYPE) ) { SetRecvData(_T("服务器已创建!\r\n")); m_bConnect = TRUE; SetConectState(TRUE); SetNetSetCtrlEnable(FALSE); ResizeRecvCtrl(TRUE); SetSerCtrlAreaVisable(TRUE); //SetCliCtrlAreaVisable(FALSE); } else { SetRecvData(_T("创建服务器失败!\r\n")); } return; }// if (!m_bConnect) } // 遍历本地tcp端口 被占用返回TRUE,否则返回FALSE BOOL CNetAssistDlg::CheckPortIsOccupy(DWORD dwPort) { PMIB_TCPTABLE pTcptable; pTcptable = (MIB_TCPTABLE*)malloc(sizeof(MIB_TCPTABLE)); DWORD dwsize = sizeof(MIB_TCPTABLE); if (GetTcpTable(pTcptable, &dwsize, 2) == ERROR_INSUFFICIENT_BUFFER) { free(pTcptable); pTcptable = (PMIB_TCPTABLE)malloc(dwsize); } if (GetTcpTable(pTcptable, &dwsize, 2) == NO_ERROR) { for (int i = 0; i < (int)pTcptable->dwNumEntries; i++) { DWORD port = ntohs(pTcptable->table[i].dwLocalPort); if (port == dwPort) { return TRUE; } } } free(pTcptable); return FALSE; } // TCP Client void CNetAssistDlg::TCPCliConOrDis() { // 已连接的情况下,断开连接 if ( m_bConnect ) { m_client.CloseSocket(); if ( !m_client.IsConnect() ) { SetRecvData(_T("已与服务器断开连接!\r\n")); m_bConnect = FALSE; SetConectState(FALSE); SetNetSetCtrlEnable(TRUE); ResizeRecvCtrl(FALSE); SetCliCtrlAreaVisable(FALSE); } else { SetRecvData(_T("断开连接失败!\r\n")); } return; } // 未连接的情况下,连接 if ( !m_bConnect ) { m_client.SetSockType(TCP_TYPE); // 获取IPAddrCtrl中的地址 CString strIP = GetIPAddr(&m_ipa_lochostIP); char *szIp = strIP.GetBuffer(0); strIP.ReleaseBuffer(); // 获取端口号 DWORD dwPort = GetPort(&m_edt_locHostPort); if ( m_client.ConnectServer(szIp, dwPort) ) { SetRecvData(_T("连接服务器成功!\r\n")); m_bConnect = TRUE; SetConectState(TRUE); SetNetSetCtrlEnable(FALSE); ResizeRecvCtrl(TRUE); SetCliCtrlAreaVisable(TRUE); m_stc_tarHost.SetWindowText(_T("本地主机:")); m_stc_tarPort.SetWindowText(_T("本地端口:")); } else { SetRecvData(_T("连接服务器失败!\r\n")); } return; } } // 获取IP CString CNetAssistDlg::GetIPAddr(CIPAddressCtrl *ipCtrl) { BYTE byField0, byField1, byField2, byField3; ipCtrl->GetAddress(byField0, byField1, byField2, byField3); CString strIP; strIP.Format("%d.%d.%d.%d", byField0, byField1, byField2, byField3); return strIP; } // 获取端口号 DWORD CNetAssistDlg::GetPort(CEdit *edtCtrl) { CString strPort; edtCtrl->GetWindowText(strPort); int nPort = _ttoi(strPort); return (DWORD)nPort; } // 设置接收区内容 void CNetAssistDlg::SetRecvData(CString strData) { CString strOld; m_edt_recvData.GetWindowText(strOld); char buff[128]; int nCount = m_edt_recvData.GetLine( m_edt_recvData.GetLineCount() - 1, buff, 128); if ( m_ckb_recv2.GetCheck() && nCount != 0) strData = _T("\r\n") + strData; strOld += strData; m_edt_recvData.SetWindowText(strOld); int nLineCount = m_edt_recvData.GetLineCount(); m_edt_recvData.LineScroll(nLineCount - 1); // 设置滚动条一直在底部 } // 发送信息 void CNetAssistDlg::OnBnClickedBtnSenddata() { if ( !m_bConnect ) { AfxMessageBox(_T("网络未连接,发送失败!")); return; } CString strData; m_edt_sendData.GetWindowText(strData); char *pszData = strData.GetBuffer(0); strData.ReleaseBuffer(); switch (m_cmb_proToCol.GetCurSel()) { case 0: // UDP SendDataUdp(pszData); break; case 1: // TCP Server SendDataTcpServer(pszData); break; case 2: // TCP Client SendDataTcpClient(pszData); break; default: break; } // 发送完自动清空 if ( m_ckb_send3.GetCheck() ) m_edt_sendData.SetWindowText(_T("")); } // 发送消息 // UDP void CNetAssistDlg::SendDataUdp(char *pszData) { AfxMessageBox(_T("UDP通信暂不可用!")); } // TCP Server void CNetAssistDlg::SendDataTcpServer(char *pszData) { if (pszData == NULL) return; UINT nLen = strlen(pszData); int nItem = m_cmb_conTar.GetCurSel(); if (nItem == 0) // All Connections { for (UINT i = 0; i < m_VecSocket.size(); i++) { long nSendRet = m_server.SendData(m_VecSocket.at(i), pszData, nLen); if (nSendRet < 0) { SetRecvData(_T("\r\n发送消息失败!")); continue; } m_nSendCount += nLen; SetSendNum(); } } else { long nSendRet = m_server.SendData(m_VecSocket.at(nItem-1), pszData, nLen); if (nSendRet < 0) { SetRecvData(_T("\r\n发送消息失败!")); return; } m_nSendCount += nLen; SetSendNum(); } } // TCP Client void CNetAssistDlg::SendDataTcpClient(char *pszData) { if (pszData == NULL) return; UINT nLen = strlen(pszData); int nSendRet = m_client.SendData(pszData, nLen); if (nSendRet m_VecSocket.push_back(newSocket); CString strAddr = inet_ntoa(szSockAddr->sin_addr); // 得到发送者IP地址 char szPort[6]; itoa(szSockAddr->sin_port, szPort, 10); // 得到发送者本地端口 CString strAddrPort = strAddr + _T(":") + szPort; p->m_cmb_conTar.AddString(strAddrPort); p->m_stc_newCon.SetWindowText(_T("New Connection:") + strAddrPort); } // 接收消息 void SNewMsgCallBack(const SOCKADDR_IN *pSockAddr, const SOCKET_HAND *pSocketHand, const SOCKET_DATA *pData, void *pUserParam) { CNetAssistDlg *p = (CNetAssistDlg *)pUserParam; CString strAddr = inet_ntoa(pSockAddr->sin_addr); // 得到发送者IP地址 char szPort[6]; itoa(pSockAddr->sin_port, szPort, 10); // 得到发送者本地端口 CString strAddrPort = strAddr + _T(":") + szPort; CString strAddrPortOld = g_strAddrAndPort; g_strAddrAndPort = strAddrPort; if (strAddrPortOld != strAddrPort) { p->SetRecvData(_T("【Receive from ") + strAddrPort + _T("】:\r\n")); } p->SetRecvData(pData->pData); p->m_nRecvCount += pData->len; p->SetRecvNum(); } // 客户端断开连接 void SCloseSocketCallBack(const char *szSocket, SOCKET newSocket, void *pUserParam) { CNetAssistDlg *p = (CNetAssistDlg *)pUserParam; p->m_stc_newCon.SetWindowText(szSocket); if (p->m_VecSocket.empty()) return; UINT nItem = p->findSocketInVector(newSocket); if (nItem != -1) { p->m_cmb_conTar.DeleteString(nItem+1); p->m_cmb_conTar.SetCurSel(nItem); } } // 返回-1表示失败,否则返回索引 UINT CNetAssistDlg::findSocketInVector(SOCKET newSocket) { UINT nItem = -1; UINT i = 0; for (vector::iterator it = m_VecSocket.begin(); it != m_VecSocket.end(); ) { if (*it == newSocket) { m_VecSocket.erase(it); nItem = i; break; } it++; i++; } return nItem; } // 客户端 Client // 接收消息 void CNewMsgCallBack(long nPort, SOCKET svrSocket, const SOCKET_DATA* pData, void * pUserParam) { CNetAssistDlg *p = (CNetAssistDlg *)pUserParam; p->SetRecvData(pData->pData); p->m_nRecvCount += pData->len; p->SetRecvNum(); CString strPort; strPort.Format("%d", nPort); p->m_edt_tarPort.SetWindowText(strPort); } // 服务器断开连接 void CDisconnetCallBack(void *pUsr) { AfxMessageBox("此函数为什么不会响应??"); CNetAssistDlg *p = (CNetAssistDlg *)pUsr; p->SetRecvData(_T("\r\n服务器已下线!")); p->OnBnClickedBtnCondis(); } // 串口关闭前,判断套接字是否关闭 void CNetAssistDlg::OnClose() { m_server.StopListening(); if (m_client.IsConnect()) m_client.CloseSocket(); CDialog::OnClose(); } void CNetAssistDlg::OnMenuAboutBtnClicked() { CAboutDlg dlg; dlg.DoModal(); } void CNetAssistDlg::OnMenuexitbtn() { EndDialog(0); }

 

                                                    3.  说明

CServerSocket类和CClientSocket类是对socket的封装,该类由动态链接库导出,这里不提供源码,项目里有该动态链接库的头文件和相应的DLL和LIB文件,下载地址请转至文末查看。

 

                                              4.   项目下载地址

https://download.csdn.net/download/wu9797/10562075



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3