Wireshark使用以下详细信息捕获LAN中的UDP数据包
Source IP 192.168.1.2 Destination IP 233.x.x.x Source Port 24098 Destination Port 12074,12330
我怎样才能在c#中捕获它?
自己解决了
这是我的工作代码
class CAA { private Socket UDPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); private IPAddress Target_IP; private int Target_Port; public static int bPause; public CAA() { Target_IP = IPAddress.Parse("x.x.x.x"); Target_Port = xxx; try { IPEndPoint LocalHostIPEnd = new IPEndPoint(IPAddress.Any, Target_Port); UDPSocket.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.NoDelay, 1); UDPSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1); UDPSocket.Bind(LocalHostIPEnd); UDPSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 0); UDPSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(Target_IP)); Console.WriteLine("Starting Recieve"); Recieve(); } catch (Exception e) { Console.WriteLine(e.Message + " " + e.StackTrace); } } private void Recieve() { try { IPEndPoint LocalIPEndPoint = new IPEndPoint(IPAddress.Any, Target_Port); EndPoint LocalEndPoint = (EndPoint)LocalIPEndPoint; StateObject state = new StateObject(); state.workSocket = UDPSocket; Console.WriteLine("Begin Recieve"); UDPSocket.BeginReceiveFrom(state.buffer, 0, state.BufferSize, 0, ref LocalEndPoint, new AsyncCallback(ReceiveCallback), state); } catch (Exception e) { Console.WriteLine(e.ToString()); } } private void ReceiveCallback(IAsyncResult ar) { IPEndPoint LocalIPEndPoint = new IPEndPoint(IPAddress.Any, Target_Port); EndPoint LocalEndPoint = (EndPoint)LocalIPEndPoint; StateObject state = (StateObject)ar.AsyncState; Socket client = state.workSocket; int bytesRead = client.EndReceiveFrom(ar, ref LocalEndPoint); client.BeginReceiveFrom(state.buffer, 0, state.BufferSize, 0, ref LocalEndPoint, new AsyncCallback(ReceiveCallback), state); } public static void Main() { CAA o = new CAA(); Console.ReadLine(); } public class StateObject { public int BufferSize = 512; public Socket workSocket; public byte[] buffer; public StateObject() { buffer = new byte[BufferSize]; } } }
该Winpcap的图书馆是做到这一点的最佳途径之一.我有使用C#这样做的经验,并且使用这个库非常容易.
该项目展示了如何使用C#完成它.
Wireshark实际上使用Winpcap来做到这一点,正如另一个答案所示,你也可以使用它.
您也可以使用System.Net.Sockets.Socket
该类并将其置于混杂模式.我用它来从给定的网络接口捕获IP流量(例如,TCP和UDP).这是一个例子.
using System.Net; using System.Net.Sockets; Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP); socket.Bind(new IPEndPoint(IPAddress.Parse("X.X.X.X"), 0)); // specify IP address socket.ReceiveBufferSize = 2 * 1024 * 1024; // 2 megabytes socket.ReceiveTimeout = 500; // half a second byte[] incoming = BitConverter.GetBytes(1); byte[] outgoing = BitConverter.GetBytes(1); socket.IOControl(IOControlCode.ReceiveAll, incoming, outgoing);
现在已创建并配置套接字,您可以使用该Receive()
方法开始接收数据.每次调用时Receive()
,返回的缓冲区都将包含一个IP数据包.有关IPv4标头的详细信息,请参见此处,此处为UDP标头,此处为TCP标头.如果IP标头的Protocol字段包含值17,那么您有一个UDP数据包.
注意 Windows上的原始套接字要求您是本地系统的管理员.本MSDN文章中包含以下语言.
要使用SOCK_RAW类型的套接字,需要管理权限.运行使用原始套接字的Winsock应用程序的用户必须是本地计算机上Administrators组的成员,否则原始套接字调用将失败,错误代码为WSAEACCES.在Windows Vista及更高版本中,在创建套接字时强制访问原始套接字.在早期版本的Windows中,在其他套接字操作期间强制访问原始套接字.