新手入了MFC的坑,做MFC网络调试助手,记录:
1.效果图,下方有连接(免费)
2.网络调试助手功能较完善,不支持中文转16进制,目前没想到好方法,欢迎交流
3,socket通信使用MFC封装的CSocket类,搞清楚通信的流程很重要,这样的文章有很多
4,进制之间的转化,这个涉及到进制之间的互相转化,因该多去学习
5,各种控件的使用。
socket的通信,TCP 服务器 Create,bind ,listen ,accept, send/Receive
客户端:create ,connect ,send/Receive
这个软件 支持TCP server /TCP client /UDP 三种通信方式,设计CSocket派生类,CSocku 用于接收UDP通信的消息,CClientSocket用于接收服务器发送来的消息,CConnectSocket类接收客户端发送来的消息。在三个派生类中添加OnReceive虚消息。CnettestDlg中服务发送消息。CListenSocket中用CPtrlist存放每一个访问的客户端地址。
nettest.h
// nettest.h : PROJECT_NAME 应用程序的主头文件
//
#pragma once
#ifndef __AFXWIN_H__
#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif
#include "resource.h" // 主符号
// CnettestApp:
// 有关此类的实现,请参阅 nettest.cpp
//
class CnettestApp : public CWinApp
{
public:
CnettestApp();
CPtrList m_list;//用来存放每一个客户端
// 重写
public:
virtual BOOL InitInstance();
// 实现
DECLARE_MESSAGE_MAP()
};
extern CnettestApp theApp;
nettestDlg.h
// nettestDlg.h : 头文件
//
#pragma once
#include "afxwin.h"
#include"ClientSocket.h"
#include"ConnectSocket.h"
#include"ListenSocket.h"
#include "afxcmn.h"
#include"Socku.h"
// CnettestDlg 对话框
class CnettestDlg : public CDialogEx
{
// 构造
public:
CnettestDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_NETTEST_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()
public:
afx_msg void OnBnClickedCheck5();
CComboBox m_comb;
CConnectSocket m_connectsock;
CListenSocket m_listensock;
CSocku m_socku;
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedCancel();
afx_msg void OnBnClickedButton1();
sockaddr_in addr;
afx_msg void OnBnClickedButton2();
CEdit m_revEdit;
CProgressCtrl m_progress;
CEdit m_sendEdit;
afx_msg void OnTimer(UINT_PTR nIDEvent);
CButton m_sendclear;
CButton m_timer;
afx_msg void OnBnClickedButton3();
CString Hex2Ascii(CString str_HEX);
CString CStringtoHex(CString str);
CButton m_send16;
afx_msg void OnBnClickedCheck3();
CButton m_sendtime;
afx_msg void OnBnClickedCount();
CEdit m_sendCOUNT;
UINT GetCount(CString strsum);
};
Socku.cpp
// Socku.cpp : 实现文件
//
#include "stdafx.h"
#include "nettest.h"
#include "Socku.h"
// CSocku
CSocku::CSocku()
{
}
CSocku::~CSocku()
{
}
// CSocku 成员函数
int RECEIVECOUNT = 0;
void CSocku::OnReceive(int nErrorCode)
{
CWnd *pWnd = AfxGetMainWnd();
/*SOCKADDR_IN ClientAddr;
int len = sizeof(SOCKADDR_IN);*/
char s[2048] = { 0 };
CString sIP;
UINT nPort;
//int nLen=ReceiveFrom(s, sizeof(s), (SOCKADDR*)&ClientAddr, &len, 0);
int nLen = ReceiveFrom(s, sizeof(s), sIP, nPort);
if (nLen < 0)
return;
//CString rource(s);
CString strl;
strl.Format(_T("%s"), s); //char * 转CString 类型
//strtol(s, NULL, 16);
//16进制输出,不支持中文 待完成
int length = strl.GetLength();
CString temp;
CString str_HEX;
//CString str_HEXSUM;
for (int i = 0; i < length; i++)
{
temp.Format(_T("%2X"), strl.GetAt(i));
// int n = _ttoi(temp);
// int x = printf("%x", n);
// str_HEX.Format(x);
str_HEX = str_HEX + _T(" ") + temp;
}
CButton *pCheck = (CButton*)pWnd->GetDlgItem(IDC_CHECK1);
CString strsum = _T("");
int nstate = pCheck->GetCheck();
if (nstate == BST_CHECKED)
{
strsum = str_HEX;
}
else
{
strsum = strl;
}
//接收区 计数
CEdit *pEdit1 = (CEdit*)pWnd->GetDlgItem(IDC_RECEIVECOUNT);
CString strCOUNT;
pEdit1->GetWindowText(strCOUNT);
int number = _ttoi(strCOUNT);
int SUM = number + GetCount(strsum);
CString inttostring;
inttostring.Format(_T("%d"), SUM);
pEdit1->SetWindowText(inttostring);
pEdit1->UpdateData(FALSE);
/*CString strcount;
strcount.Format(_T("%d"), RECEIVECOUNT);*/
//pEdit1->SetWindowText(strcount);
CString strtime;
strtime = Time();
CString szIP;
CString nPORT;
CEdit *pEditIP = (CEdit*)pWnd->GetDlgItem(IDC_IP);
pEditIP->GetWindowText(szIP);
CEdit *pEditPORT = (CEdit*)pWnd->GetDlgItem(IDC_PORT);
pEditPORT->GetWindowText(nPORT);
CString str;
str.Format(_T("Receive form % sPort %d:%s"), szIP, nPort, strsum);
CEdit *pEdit = (CEdit*)pWnd->GetDlgItem(IDC_RECEIVE);
pEdit->SetSel(pEdit->GetWindowTextLength(), -1);
pEdit->ReplaceSel(_T(" \r\n") +strtime+str + _T("\r\n"));
CSocket::OnReceive(nErrorCode);
}
CString CSocku::Time()
{
CTime t = CTime::GetCurrentTime();
int nYear = t.GetYear();
int nMonth = t.GetMonth();
int nDay = t.GetDay();
int nHour = t.GetHour();
int nMin = t.GetMinute();
int nSec = t.GetSecond();
int nWeek = t.GetDayOfWeek();
CString str;
str.Format(_T("当前时间是:%02d年%02d月%02d日 %02d:%02d:%02d"), nYear, nMonth, nDay, nHour, nMin, nSec);
// AfxMessageBox(str);
return str;
}
UINT CSocku::GetCount(CString strsum)
{
CWnd *pWnd = AfxGetMainWnd();
int count = strsum.GetLength();
/*CString strcount;
strcount.Format(_T("%d"), count);*/
//接收字符串的计数
//CEdit *pEdit1 = (CEdit*)pWnd->GetDlgItem(IDC_RECEIVECOUNT);
//pEdit1->SetWindowText(strcount);
return count;
}
ClientSocket.cpp
// ClientSocket.cpp : 实现文件
//
#include "stdafx.h"
#include "nettest.h"
#include "ClientSocket.h"
// CClientSocket
CClientSocket::CClientSocket()
{
}
CClientSocket::~CClientSocket()
{
}
// CClientSocket 成员函数
void CClientSocket::OnAccept(int nErrorCode)
{
CSocket::OnAccept(nErrorCode);
}
UINT CClientSocket::GetCount(CString strsum)
{
CWnd *pWnd = AfxGetMainWnd();
int count = strsum.GetLength();
/*CString strcount;
strcount.Format(_T("%d"), count);*/
//接收字符串的计数
//CEdit *pEdit1 = (CEdit*)pWnd->GetDlgItem(IDC_RECEIVECOUNT);
//pEdit1->SetWindowText(strcount);
return count;
}
void CClientSocket::OnReceive(int nErrorCode)
{
char s[2048] = { 0 };
int nLen = Receive(s, sizeof(s));
if (nLen < 0)
return;
CString strl;
strl.Format(_T("%s"), s); //char * 转CString 类型
//strtol(s, NULL, 16);
//16进制输出,不支持中文 待完成
int length = strl.GetLength();
CString temp;
CString str_HEX;
//CString str_HEXSUM;
for (int i = 0; i < length; i++)
{
temp.Format(_T("%2X"), strl.GetAt(i));
// int n = _ttoi(temp);
// int x = printf("%x", n);
// str_HEX.Format(x);
str_HEX = str_HEX + _T(" ") + temp;
}
CWnd *pWnd = AfxGetMainWnd();
CButton *pCheck = (CButton*)pWnd->GetDlgItem(IDC_CHECK1);
CString strsum = _T("");
int nstate = pCheck->GetCheck();
if (nstate == BST_CHECKED)
{
strsum = str_HEX;
}
else
{
strsum = strl;
}
CEdit *pEdit1 = (CEdit*)pWnd->GetDlgItem(IDC_RECEIVECOUNT);
CString strCOUNT;
pEdit1->GetWindowText(strCOUNT);
int number = _ttoi(strCOUNT);
int SUM = number + GetCount(strsum);
CString inttostring;
inttostring.Format(_T("%d"), SUM);
pEdit1->SetWindowText(inttostring);
pEdit1->UpdateData(FALSE);
CString strtime = Time();
CString szIP;
UINT nPort;
GetPeerName(szIP, nPort);
CString str;
str.Format(_T("Receive form:%s Port %d:%s"), szIP, nPort, strsum);
//Send(s, sizeof(s));
CEdit *pEdit = (CEdit*)pWnd->GetDlgItem(IDC_RECEIVE);
pEdit->SetSel(pEdit->GetWindowTextLength(), -1);
pEdit->ReplaceSel(_T(" \r\n") +strtime+ str + _T("\r\n"));
CSocket::OnReceive(nErrorCode);
}
void CClientSocket::OnClose(int nErrorCode)
{
CPtrList &list = theApp.m_list;
POSITION pos = list.GetHeadPosition();
while (pos)
{
if (list.GetAt(pos) == this)
{
list.RemoveAt(pos);
break;
}
list.GetNext(pos);
}
delete this;
CSocket::OnClose(nErrorCode);
}
CString CClientSocket::Time()
{
CTime t = CTime::GetCurrentTime();
int nYear = t.GetYear();
int nMonth = t.GetMonth();
int nDay = t.GetDay();
int nHour = t.GetHour();
int nMin = t.GetMinute();
int nSec = t.GetSecond();
int nWeek = t.GetDayOfWeek();
CString str;
str.Format(_T("当前时间是:%02d年%02d月%02d日 %02d:%02d:%02d"), nYear, nMonth, nDay, nHour, nMin, nSec);
// AfxMessageBox(str);
return str;
}
ConnectSocket.cpp
// ConnectSocket.cpp : 实现文件
//
#include "stdafx.h"
#include "nettest.h"
#include "ConnectSocket.h"
// CConnectSocket
CConnectSocket::CConnectSocket()
{
}
CConnectSocket::~CConnectSocket()
{
}
// CConnectSocket 成员函数
UINT CConnectSocket::GetCount(CString strsum)
{
CWnd *pWnd = AfxGetMainWnd();
int count = strsum.GetLength();
/*CString strcount;
strcount.Format(_T("%d"), count);*/
//接收字符串的计数
//CEdit *pEdit1 = (CEdit*)pWnd->GetDlgItem(IDC_RECEIVECOUNT);
//pEdit1->SetWindowText(strcount);
return count;
}
void CConnectSocket::OnReceive(int nErrorCode)
{
char s[2048] = { 0 };
int nLen = Receive(s, sizeof(s));
if (nLen < 0)
return;
//CString rource(s);
CWnd *pWnd = AfxGetMainWnd();
CString strl;
strl.Format(_T("%s"), s); //char * 转CString 类型
//strtol(s, NULL, 16);
//16进制输出,不支持中文 待完成
int length = strl.GetLength();
CString temp;
CString str_HEX;
//CString str_HEXSUM;
for (int i = 0; i < length; i++)
{
temp.Format(_T("%2X"), strl.GetAt(i));
// int n = _ttoi(temp);
// int x = printf("%x", n);
// str_HEX.Format(x);
str_HEX = str_HEX + _T(" ") + temp;
}
CButton *pCheck = (CButton*)pWnd->GetDlgItem(IDC_CHECK1);
CString strsum = _T("");
int nstate = pCheck->GetCheck();
if (nstate == BST_CHECKED)
{
strsum = str_HEX;
}
else
{
strsum = strl;
}
CEdit *pEdit1 = (CEdit*)pWnd->GetDlgItem(IDC_RECEIVECOUNT);
CString strCOUNT;
pEdit1->GetWindowText(strCOUNT);
int number = _ttoi(strCOUNT);
int SUM = number + GetCount(strsum);
CString inttostring;
inttostring.Format(_T("%d"), SUM);
pEdit1->SetWindowText(inttostring);
pEdit1->UpdateData(FALSE);
CString strtime = Time();
CString szIP;
UINT nPort;
GetPeerName(szIP, nPort);
CString str;
str.Format(_T("Receive form % sPort %d:%s"), szIP, nPort, strsum);
CEdit *pEdit = (CEdit*)pWnd->GetDlgItem(IDC_RECEIVE);
pEdit->SetSel(pEdit->GetWindowTextLength(), -1);
pEdit->ReplaceSel(_T(" \r\n") + strtime+str + _T("\r\n"));
CSocket::OnReceive(nErrorCode);
}
CString CConnectSocket::Time()
{
CTime t = CTime::GetCurrentTime();
int nYear = t.GetYear();
int nMonth = t.GetMonth();
int nDay = t.GetDay();
int nHour = t.GetHour();
int nMin = t.GetMinute();
int nSec = t.GetSecond();
int nWeek = t.GetDayOfWeek();
CString str;
str.Format(_T("当前时间是:%02d年%02d月%02d日 %02d:%02d:%02d"), nYear, nMonth, nDay, nHour, nMin, nSec);
// AfxMessageBox(str);
return str;
}
ListenSocket.cpp
// ListenSocket.cpp : 实现文件
//
#include "stdafx.h"
#include "nettest.h"
#include "ListenSocket.h"
#include"ClientSocket.h"
// CListenSocket
CListenSocket::CListenSocket()
{
}
CListenSocket::~CListenSocket()
{
}
// CListenSocket 成员函数
CClientSocket *pSock = NULL;
void CListenSocket::OnAccept(int nErrorCode)
{
pSock = new CClientSocket;
Accept(*pSock);
theApp.m_list.AddTail(pSock);
/*else
delete pSock;*/
CSocket::OnAccept(nErrorCode);
}
总之,先搭起socket通信的架子,剩下的东西再往里塞就可以了。