随便转载,转载请注明出处http://blog.youkuaiyun.com/leotangcw/
欢迎大家和我交流QQ:17371764 Email:tangchengwen@163.com
今天学校开运动会了,和同学在看台最后一排打扑克,呵呵,输了4块,郁闷,一开始牌很好的,后来就不行了,大四了对学校这些活动都有一种看穿一切的感觉
昨天主要做了设置页面,今天主要是做数据包的捕获了,其实数据包的捕获主要是几个winpcap函数,现在的参考书目很多都是在dos下的捕包,所以很多都用了winpcap的pcap_loop函数来捕包,再通过一个回掉函数来做包处理,但是在MFC下回掉函数一般要写到一个类里面,这样我们就得把它申明成静态得函数,但是静态函数在后期操作上面又有很多问题,但是我也想了看有没什么好方法,结果最后放弃用loop函数而用了pcap_next_ex这个函数,回头一翻winpcap开发手册,发现里面有这样得提示:在Capturing the packets without the callback那个例子里面原文如下:The example program in this lesson behaves exactly like the previous program (Opening an adapter and capturing the packets), but it uses pcap_next_ex() instead of pcap_loop().
The callback-based capture mechanism of pcap_loop() is elegant and it could be a good choice in some situations. However, handling a callback is sometimes not practical -- it often makes the program more complex especially in situations with multithreaded applications or C++ classes.
In these cases, pcap_next_ex() retrievs a packet with a direct call -- using pcap_next_ex() packets are received only when the programmer wants them.
看来我的选择还是对的,这也是winpcap开发包推荐的选择。这样在选好了捕包函数后就是界面的问题了,我创建了SDI的工程,做了一个切分窗口,就是在CMainFrame类里面重载OnCreateClient函数,添加类式如下的代码m_splitter.CreateStatic(this,2,1);
m_splitter.CreateView(0,0,RUNTIME_CLASS(CSetupdlgView),CSize(400,400),pContext);
m_splitter.CreateView(1,0,RUNTIME_CLASS(CViewDown),CSize(200,200),pContext);
m_splitter是一个声明的CSplitterWnd变量,我视图的上面部分是从CListView派生的,下面部分嵌入了一个从CFormView继承的Dialog程序运行后的情况如下:
我们先开始上面部分的代码编写,一开始在OnInitialUpdate()做初始化list,代码大概如下:
CListCtrl& theCtrl = GetListCtrl();
DWORD dwStyle;
dwStyle = theCtrl.GetExtendedStyle();//GetStyle();
dwStyle |=LVS_EX_FULLROWSELECT;
theCtrl.SetExtendedStyle(dwStyle);
// Insert a column. This override is the most convenient.
theCtrl.InsertColumn(0, _T("序号"), LVCFMT_LEFT); //初始化列名
theCtrl.InsertColumn(1, _T("捕获时间"), LVCFMT_LEFT);
theCtrl.InsertColumn(2, _T("包长度"), LVCFMT_LEFT);
theCtrl.InsertColumn(3, _T("源IP"), LVCFMT_LEFT);
theCtrl.InsertColumn(4, _T("目的IP"), LVCFMT_LEFT);
theCtrl.InsertColumn(5, _T("源物理地址"), LVCFMT_LEFT);
theCtrl.InsertColumn(6, _T("目的物理地址"),LVCFMT_LEFT);
theCtrl.InsertColumn(7, _T("使用协议"), LVCFMT_LEFT);
theCtrl.InsertColumn(8, _T("相关信息"), LVCFMT_LEFT);
theCtrl.SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER);
theCtrl.SetColumnWidth(1, 160);
theCtrl.SetColumnWidth(2, LVSCW_AUTOSIZE_USEHEADER);
theCtrl.SetColumnWidth(3, 110);
theCtrl.SetColumnWidth(4, 110);
theCtrl.SetColumnWidth(5,120);
theCtrl.SetColumnWidth(6,120);
theCtrl.SetColumnWidth(7,90);
theCtrl.SetColumnWidth(8,150);
记得先要在PreCreateWindow(CREATESTRUCT& cs)中调整style以便后面做整行选择
cs.style |= LVS_REPORT|LVS_SINGLESEL ;
接着把从设置对话框传来得参数传如自己写的捕包函数开始捕包,大家可以看到其实我得函数写的很不是地方,写到了View里面,但是图简单,不想弄了,呵呵!
从设置页传回来的接口参数只传了选择的接口的序号(没直接传接口指针),所以只有再遍历一便接口。
还有就是为了不让程序进入失去相应状态,而且也为了提高效率,我开辟了另一个线程捕包,但是我以前没写过多线程的程序,写的很不好,参数传递全是通过全局变量传递的