دریافت پاکت ها بدون استفاده از CallBack
مثال این درس عملکردی بسیار شبیه به مثال درس قبلی دارد.(آداپتور را باز کرده و پاکت ها را ضبط می کند). با این تفاوت که به جای RecivePackets() از RecivePacket() استفاده می کند.
مکانیزم مبتنی بر CallBack برای ضبط پاکت ها ساده و روان است و برای برخی از حالات کاملاٌ مناسب است. به هر حال، فراخوانی CallBack روش کارآمدی نیست زیرا برنامه را در حالت هایی که از چند رشته ای استفاده می کند بسیار پیچیده می کند.
در این حالت ها، تابع RecivePacket() دریافت را بافراخوانی مستقیم انجام می دهد.با استفاده از RecivePacket() پاکت ها تنها زمانی مه برنامه نویس می خواهد دریافت می شود.پارامتر این تابع تنها یک تابع خروجی است که پاکت ها را دریافت می کند..
در مثال بعدی، کد CallBack مثال قبلی را حذف کرده ایم و به درون Main() و بعد از فراخوانی RecivePacket() انتقال دادیم.
using
System; using
System.Collections.Generic; using
PcapDotNet.Core; using
PcapDotNet.Packets; namespace
CapturingThePacketsWithoutTheCallback { class
Program { static void
Main(string[]
args) { //
Retrieve the device list from the local machine IList<LivePacketDevice>
allDevices = LivePacketDevice.AllLocalMachine; if
(allDevices.Count == 0) { Console.WriteLine("No
interfaces found! Make sure WinPcap is installed."); return; } //
Print the list for (int i
= 0; i != allDevices.Count; ++i) { LivePacketDevice device =
allDevices[i]; Console.Write((i + 1) + ".
" + device.Name); if
(device.Description != null) Console.WriteLine("
(" + device.Description + ")"); else Console.WriteLine("
(No description available)"); } int
deviceIndex = 0; do { Console.WriteLine("Enter
the interface number (1-" + allDevices.Count + "):"); string
deviceIndexString = Console.ReadLine(); if (!int.TryParse(deviceIndexString,
out
deviceIndex) || deviceIndex < 1 ||
deviceIndex > allDevices.Count) { deviceIndex = 0; } } while
(deviceIndex == 0); //
Take the selected adapter PacketDevice selectedDevice =
allDevices[deviceIndex - 1]; //
Open the device using
(PacketCommunicator communicator = selectedDevice.Open(65536, // portion
of the packet to capture
// 65536 guarantees that the whole packet
will be captured on all the link layers
PacketDeviceOpenAttributes.Promiscuous, //
promiscuous mode 1000)) //
read timeout { Console.WriteLine("Listening
on " + selectedDevice.Description + "..."); //
Retrieve the packets Packet packet; do {
PacketCommunicatorReceiveResult result = communicator.ReceivePacket(out
packet); switch
(result) { case
PacketCommunicatorReceiveResult.Timeout: //
Timeout elapsed continue; case
PacketCommunicatorReceiveResult.Ok:
Console.WriteLine(packet.Timestamp.ToString("yyyy-MM-dd
hh:mm:ss.fff") + "
length:" +
packet.Length); break; default: throw new
InvalidOperationException("The result " +
result + " shoudl never be reached here"); } } while (true); } } } }
توجه کنید که RecivePacket() مقادیر مختلفی را برای حالت های موفقیت ، انقضای زمان BreakLoop و EOF برمی گرداند.