以 SharpPcap 實作可收聽封包的 C# 程式(winform)
上一篇文章是介紹如何撰寫簡單的console程式,這篇將分享我實作 SharpPcap winform 程式的心得和遇到的問題。
winform表單設計
一個TextBox,作用是輸入過濾封包的filter到TextBox。
一個ListBox,作用是選擇ListBox中的網卡設備。
兩個Button。作用是開始時按下開始監聽按鈕,結束時按下停止監聽。
form.cs程式碼
設定完介面之後,我在 form.cs 引用 SharpPcap 的元件,並在Form class中先宣告網卡設備清單。然後在 Form 的初始函式中獲取網卡清單並在入到 Listbox 中。
觸發事件的程式碼
我有三個事件要寫,一個是開始監聽某網卡封包的按鈕事件、一個是停止監聽的按鈕事件、一個是封包被抓取時的觸發事件。第一個按鈕事件有兩個條件要先檢查,是否選擇了監聽的網卡,是否輸入封包過條件。條件都滿足之後再啟動網卡設備。
第二個封包觸發事件,我希望當觸發時能在UI上提示一些訊息。但因為UI的執行緒和觸發事件發生時的不同,我並不能直接在事件中修改UI,除錯時系統會跳出跨執行緒的警告,並終止程式。因此我要先確認該控制項的 InvokeRequired 屬性,若為真表示跨執行緒調用,必須透過控制項的 BeginInvoke 方法才能調用。若不為真我才能直接調用。
以上,這是本次的sharpcap winform 實作分享。
winform表單設計
一個TextBox,作用是輸入過濾封包的filter到TextBox。
一個ListBox,作用是選擇ListBox中的網卡設備。
兩個Button。作用是開始時按下開始監聽按鈕,結束時按下停止監聽。
form.cs程式碼
設定完介面之後,我在 form.cs 引用 SharpPcap 的元件,並在Form class中先宣告網卡設備清單。然後在 Form 的初始函式中獲取網卡清單並在入到 Listbox 中。
using SharpPcap;
using SharpPcap.LibPcap;
using PacketDotNet;
namespace webcam_alarm_for_skype
{
public partial class Form1 : Form
{
LibPcapLiveDeviceList devicelist = LibPcapLiveDeviceList.Instance;
public Form1()
{
InitializeComponent();
for (int i = 0; i < devicelist.Count; i++)
{
ListBox.Items.Add(devicelist[i].Description);
}
}
}
}
觸發事件的程式碼
我有三個事件要寫,一個是開始監聽某網卡封包的按鈕事件、一個是停止監聽的按鈕事件、一個是封包被抓取時的觸發事件。第一個按鈕事件有兩個條件要先檢查,是否選擇了監聽的網卡,是否輸入封包過條件。條件都滿足之後再啟動網卡設備。
/*開始監聽的按鈕事件*/
private void button_Click(object sender, EventArgs e)
{
if (ListBox.SelectedIndex < 1)
{
MessageBox.Show("沒選網卡!!", "提示", MessageBoxButtons.OK);
}
else if (TextBox.Text == "")
{
MessageBox.Show("沒有封包過濾的條件!!", "提示", MessageBoxButtons.OK);
}
else
{
LibPcapLiveDevice lpldevice = devicelist[ListBox.SelectedIndex - 1];
try
{
/* 選擇其中一個網卡,不一定要開啟混亂模式 */
lpldevice.Open(DeviceMode.Promiscuous, 1000);
/* 使用符合 tcpdump 格式的語法即可過濾封包,基本上 http 的封包可用 tcp and ip 過濾*/
lpldevice.Filter = TextBox.Text;
/* 當條件的封包被被截取時,執行 device_OnPacketArrival */
lpldevice.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival);
/* 開始 */
lpldevice.StartCapture();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK);
}
}
}
/*停止監聽的按鈕事件*/
private void button2_Click(object sender, EventArgs e)
{
/* 選擇其中一個網卡 */
LibPcapLiveDevice lpldevice = devicelist[lst_intefaces.SelectedIndex - 1];
lpldevice.StopCapture();
}
第二個封包觸發事件,我希望當觸發時能在UI上提示一些訊息。但因為UI的執行緒和觸發事件發生時的不同,我並不能直接在事件中修改UI,除錯時系統會跳出跨執行緒的警告,並終止程式。因此我要先確認該控制項的 InvokeRequired 屬性,若為真表示跨執行緒調用,必須透過控制項的 BeginInvoke 方法才能調用。若不為真我才能直接調用。
/*封包觸發事件*/
private void device_OnPacketArrival(object sender, CaptureEventArgs e)
{
Packet dotnetpacket = Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);
TcpPacket tcpPacket = TcpPacket.GetEncapsulated(dotnetpacket);
IpPacket ippacket = (IpPacket)tcpPacket.ParentPacket;
string payload = Encoding.ASCII.GetString(tcpPacket.PayloadData);
if (payload.Contains("封包格式"))
{
if (Button.InvokeRequired)
{
Button.BeginInvoke(new MethodInvoker(
() => Button.value = "過濾到了!!"));
}
else
{
Button.value = "過濾到了!!";
}
}
}
以上,這是本次的sharpcap winform 實作分享。
留言
張貼留言