i'm tryin' to read the content of the packets that i've captured with SharpPCap.
This is my little code
private void button4_Click(object sender, EventArgs e)
{
// Retrieve the device list
var devices = LibPcapLiveDeviceList.Instance;
// Extract a device from the list
var device = devices[1];
// Register our handler function to the
// 'packet arrival' event
device.OnPacketArrival +=
new SharpPcap.PacketArrivalEventHandler(device_OnPacketArrival);
// Open the device for capturing
int readTimeoutMilliseconds = 1000;
if (device is AirPcapDevice)
{
// NOTE: AirPcap devices cannot disable local capture
var airPcap = device as AirPcapDevice;
airPcap.Open(SharpPcap.WinPcap.OpenFlags.DataTransferUdp, readTimeoutMilliseconds);
}
else if (device is WinPcapDevice)
{
var winPcap = device as WinPcapDevice;
winPcap.Open(SharpPcap.WinPcap.OpenFlags.DataTransferUdp | SharpPcap.WinPcap.OpenFlags.NoCaptureLocal, readTimeoutMilliseconds);
}
else if (device is LibPcapLiveDevice)
{
var livePcapDevice = device as LibPcapLiveDevice;
livePcapDevice.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
}
else
{
throw new System.InvalidOperationException("unknown device type of " + device.GetType().ToString());
}
device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
device.StartCapture();
MessageBox.Show("-- Listening on {0}, hit 'Enter' to stop...",
device.Description);
// Stop the capturing process
device.StopCapture();
// Close the pcap device
device.Close();
}
private static void device_OnPacketArrival(object sender, CaptureEventArgs e)
{
if (e.Packet.LinkLayerType == PacketDotNet.LinkLayers.Ethernet)
{
var packet = PacketDotNet.Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);
var ethernetPacket = (PacketDotNet.EthernetPacket)packet;
MessageBox.Show(System.Text.Encoding.ASCII.GetString(e.Packet.Data));
packetIndex++;
}
}
I capture a byte[] packet but i don't know how can i read the whole server response.
thank you for the help
Related
The main question is: could c# application track moment when user starts to upload file from his local machine to internet? It might be any process on machine. Tracking application does not triggered uploading file process.
There is example of code that captures so much outgoing TCP and UDP traffic. But I need to filter only packets contain file transferring data.
public static void Start()
{
//get ip address
IPAddress[] addrList = Dns.GetHostByName(Dns.GetHostName()).AddressList;
string IP = addrList[0].ToString();
//var devices = SharpPcap.WinPcap.WinPcapDeviceList.Instance;
var devices = CaptureDeviceList.Instance;
// differentiate based upon types
int count = devices.Count;
if (count < 1)
{
Console.WriteLine("No device found on this machine");
return;
}
for (int i = 0; i < count; ++i)
{
// CaptureFlowReceive(IP, i);
CaptureFlowSend(IP,i);
}
while (true)
{
//Call refresh function every 1s
RefershInfo();
}
}
private static void CaptureFlowSend(string IP, int deviceID)
{
ICaptureDevice device = CaptureDeviceList.New()[deviceID];
device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrivalSend);
int readTimeoutMilliseconds = 1000;
device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
string filter = "src host " + IP + " and ip ";
device.Filter = filter;
device.StartCapture();
}
private static void device_OnPacketArrivalSend(object sender, CaptureEventArgs e)
{
var rawCapture = e.Packet;
var packet = Packet.ParsePacket(rawCapture.LinkLayerType, rawCapture.Data);
var data = packet.PayloadPacket.PayloadPacket.PayloadData;
}
public static void RefershInfo()
{
Thread.Sleep(1000);
}
It seems I have found solution.
With netstat -a -n -o command we could receive all processes that uses tcp and udp sockets. Also we could get DiskUsage info by process from process list received in previous step. Certainly it is not perfect solution but it is almost closely that I need.
What I want to do with my application is to be able to read the characteristics of the scanned devices. I'm able to scan devices, but the scan will keep taking in whatever it finds. So I would like to have an filter for that as well. An attached picture of my results are located below my codes.
Here are my codes
using Robotics.Mobile.Core.Bluetooth.LE;
using Adapter = Robotics.Mobile.Core.Bluetooth.LE.Adapter;
var appContext = Application.Context;
_manager = (BluetoothManager)appContext.GetSystemService(BluetoothService); // ("bluetooth");
_adapter = _manager.Adapter;
_bleAdapter = new Adapter();
_bleAdapter.DeviceDiscovered += _bleAdapter_DeviceDiscovered;
_bleAdapter.ScanTimeoutElapsed += _bleAdapter_ScanTimeoutElapsed;
}
private void _bleAdapter_ScanTimeoutElapsed(object sender, EventArgs e)
{
_bleAdapter.StopScanningForDevices();
DisplayInformation("Bluetooth scan timeout elapsed, no ble devices were found");
}
private void _bleAdapter_DeviceDiscovered(object sender, DeviceDiscoveredEventArgs e)
{
var msg = string.Format(#"Device found: {0}
{1} - {2}", e.Device.Name, e.Device.ID, e.Device.Rssi);
DisplayInformation(msg);
}
private void ButtonScanBleClick(object sender, EventArgs e)
{
if (!_bleAdapter.IsScanning)
_bleAdapter.StartScanningForDevices();
}
private void DisplayInformation(string line)
{
_textboxResults.Text = $"{line}\r\n{_textboxResults.Text}";
Console.WriteLine(line);
}
Picture of my output result Here
If I understand well, you want some filter for found devices.
You have to write a bluetooth scanner callback, and then something like this:
in callback:
public void OnLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)
{
if (device.Name != null)
{
EventScanDevice(device, rssi);
}
}
in MainActivity:
List<string> scanList;
private void Scanner_EventScanDevice(BluetoothDevice device, int rssi)
{
if (!scanList.Contains(device.Name))
{
scanList.Add(device.Name + ", RSSI = " + rssi.ToString());
}
}
I have an issue about the server-client communication.
I googled around but I did not find a solution to this.
Right now I am using 32feet in order to get in touch 2 or more (till 7) BT clients to 1 BT server.
I need to broadcast a message from the server to every device in the same time, but I don't know how to do it.
The only way I figured out was to use the list of connection in order to send the message one per time, but it means a delay between each message sent (around 100 ms per device). Unfortunately it means to have a large delay on the last one.
Can someone please give me an advice on how to solve this problem?
Is there a way to broadcast the message to all devices in the same time?
If it can be helpfull, here there is the handle of connection and reading from devices.
Thanks for your help
private void btnStartServer_Click(object sender, EventArgs e)
{
btnStartClient.Enabled = false;
ConnectAsServer();
}
private void ConnectAsServer()
{
connessioniServer = new List<BluetoothClient>();
// thread handshake
Thread bluetoothConnectionControlThread = new Thread(new ThreadStart(ServerControlThread));
bluetoothConnectionControlThread.IsBackground = true;
bluetoothConnectionControlThread.Start();
// thread connessione
Thread bluetoothServerThread = new Thread(new ThreadStart(ServerConnectThread));
bluetoothServerThread.IsBackground = true;
bluetoothServerThread.Start();
}
private void ServerControlThread()
{
while (true)
{
foreach (BluetoothClient cc in connessioniServer)
{
if (!cc.Connected)
{
connessioniServer.Remove(cc);
break;
}
}
updateConnList();
Thread.Sleep(0);
}
}
Guid mUUID = new Guid("fc5ffc49-00e3-4c8b-9cf1-6b72aad1001a");
private void ServerConnectThread()
{
updateUI("server started");
BluetoothListener blueListener = new BluetoothListener(mUUID);
blueListener.Start();
while (true)
{
BluetoothClient conn = blueListener.AcceptBluetoothClient();
connessioniServer.Add(conn);
Thread appoggio = new Thread(new ParameterizedThreadStart(ThreadAscoltoClient));
appoggio.IsBackground = true;
appoggio.Start(conn);
updateUI(conn.RemoteMachineName+" has connected");
}
}
private void ThreadAscoltoClient(object obj)
{
BluetoothClient clientServer = (BluetoothClient)obj;
Stream streamServer = clientServer.GetStream();
streamServer.ReadTimeout=1000;
while (clientServer.Connected)
{
try
{
int bytesDaLeggere = clientServer.Available;
if (bytesDaLeggere > 0)
{
byte[] bytesLetti = new byte[bytesDaLeggere];
int byteLetti = 0;
while (bytesDaLeggere > 0)
{
int bytesDavveroLetti = streamServer.Read(bytesLetti, byteLetti, bytesDaLeggere);
bytesDaLeggere -= bytesDavveroLetti;
byteLetti += bytesDavveroLetti;
}
updateUI("message sent from "+clientServer.RemoteMachineName+": " + System.Text.Encoding.Default.GetString(bytesLetti));
}
}
catch { }
Thread.Sleep(0);
}
updateUI(clientServer.RemoteMachineName + " has gone");
}
private void updateUI(string message)
{
Func<int> del = delegate()
{
textBox1.AppendText(message + System.Environment.NewLine);
return 0;
};
Invoke(del);
}
private void updateConnList()
{
Func<int> del = delegate()
{
listaSensori.Items.Clear();
foreach (BluetoothClient d in connessioniServer)
{
listaSensori.Items.Add(d.RemoteMachineName);
}
return 0;
};
try
{
Invoke(del);
}
catch { }
}
I don't exactly understand how you do it right now (the italian names are not helping...) but maybe my solution can help you.
first of all, bluetooth classic does not support broadcast. so you have to deliver at one at a time.
i do connect to 7 serial port devices at a time, using 7 threads. then i tell every thread to send data. this is very close to same time, but of course not exactly.
let me know if that helps or if you need a code example.
I am just a beginner in c#. I am now trying to interface arduino with a GUI application. And i need a small function to automatically detect the port which I have connected Arduino. I tried using nested "try and catch" blocks but it failed. can anyone suggest a good way to automatic select the port in which arduino is connected and open that port such that we can move directly to coding other switches that do different functions in that arduino.
Recently i had the same situation and i wrote this method to check for our device, all you need to set your device to send specific Pattern on Specific input. In this example if you send 0x33 then your device have to send 0x8A to identify itself.
public enum SerialSignal
{
SendSync = 0x33,
ReceiveSync = 0x8A,
}
private static SerialPort _arduinoSerialPort ;
/// <summary>
/// Polls all serial port and check for our device connected or not
/// </summary>
/// <returns>True: if our device is connected</returns>
public static bool Initialize()
{
var serialPortNames = SerialPort.GetPortNames();
foreach (var serialPortName in serialPortNames)
{
try
{
_arduinoSerialPort = new SerialPort(serialPortName) { BaudRate = 9600 };
_arduinoSerialPort.Open();
_arduinoSerialPort.DiscardInBuffer();
_arduinoSerialPort.Write(new byte[] { (int)SerialSignal.SendSync }, 0, 1);
var readBuffer = new byte[1];
Thread.Sleep(500);
_arduinoSerialPort.ReadTimeout = 5000;
_arduinoSerialPort.WriteTimeout = 5000;
_arduinoSerialPort.Read(readBuffer, 0, 1);
// Check if it is our device or Not;
if (readBuffer[0] == (byte)SerialSignal.ReceiveSync){
return true;
}
}
catch (Exception ex)
{
Debug.WriteLine("Exception at Serial Port:" + serialPortName + Environment.NewLine +
"Additional Message: " + ex.Message);
}
// if the send Sync repply not received just release resourceses
if (_arduinoSerialPort != null) _arduinoSerialPort.Dispose();
}
return false;
}
public partial class Form1 : Form
{
SerialPort serial = new SerialPort();
static SerialPort cport;
public Form1()
{
InitializeComponent();
button1.Enabled = true;
button2.Enabled = false;
button3.Enabled = false;
}
private void button1_Click(object sender, EventArgs e)
{
int i;
try
{
string[] ports = SerialPort.GetPortNames();
foreach(string newport in ports)
{
cport = new SerialPort(newport, 9600);
cport.Open();
cport.WriteLine("A");
int intReturnASCII = serial.ReadByte();
char returnMessage = Convert.ToChar(intReturnASCII);
if (returnMessage == 'B')
{
button2.Enabled = true;
break;
}
else
{
cport.Close();
}
}
}
catch (Exception )
{
Console.WriteLine("No COM ports found");
}
}
I undertand that I'm a bit late, But I have created a simple and free C# NuGet library that allows for interaction between the host PC and an Arduino board!
Examples in the ReadMe.txt file.
ArduinoFace - NuGet
I have a system that sends an "at" command to a serial port and displays the return on a MessageBox.
But I needed to do this in all available serial ports. So I created a List and I'm adding all the ports on it.
I managed to send the command, but could not continue the rest of the code to catch the return because I am having trouble handling the lists. I am a beginner in C #.
Below is my current code.
The part that is commented out is what I'm struggling to continue.
This part belongs to the old code (when it was just one serial port).
public partial class Form1 : Form
{
List<SerialPort> serialPort = new List<SerialPort>();
// delegate is used to write to a UI control from a non-UI thread
private delegate void SetTextDeleg(string text);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var portNames = SerialPort.GetPortNames();
foreach (var port in portNames) {
SerialPort sp;
sp = new SerialPort(port, 19200, Parity.None, 8, StopBits.One);
sp.Handshake = Handshake.None;
//sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
sp.ReadTimeout = 500;
sp.WriteTimeout = 500;
serialPort.Add(sp);
listPorts.Items.Add(port);
}
}
private void listPorts_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
foreach (var sp in serialPort) {
// Open port
try
{
if (!sp.IsOpen)
sp.Open();
MessageBox.Show(sp.PortName + " aberto!");
sp.Write("at\r\n");
}
catch (Exception ex)
{
MessageBox.Show("Error opening/writing to serial port :: " + ex.Message, "Error!");
}
}
}
/* HELP START
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(500);
string data = sp.ReadLine();
this.BeginInvoke(new SetTextDeleg(si_DataReceived), new object[] { data });
}
private void si_DataReceived(string data)
{
String retorno = data.Trim();
MessageBox.Show(retorno);
// Fecha a porta após pegar o retorno
sp.Close();
}
HELP END */
}
What to put in place 'sp.ReadLine ();' and 'sp.Close ();'?
I don't know do this because of the List <>
The simplest approach would be to use a lambda expression which would capture the port you're using. A lambda expression is a way of building a delegate "inline" - and one which is able to use the local variables from the method you declare it in.
For example:
foreach (var port in portNames)
{
// Object initializer to simplify setting properties
SerialPort sp = new SerialPort(port, 19200, Parity.None, 8, StopBits.One)
{
Handshake = Hanshake.None,
ReadTimeout = 500,
WriteTimeout = 500
};
sp.DataReceived += (sender, args) =>
{
Thread.Sleep(500); // Not sure you need this...
string data = sp.ReadLine();
Action action = () => {
MessageBox.Show(data.Trim());
sp.Close();
};
BeginInvoke(action);
};
serialPort.Add(sp);
listPorts.Items.Add(port);
}
A few notes about this:
Just because some data has been received doesn't mean that a whole line has, so ReadLine may still block
If you only need to show a message box, you may not need Control.BeginInvoke. (If you need to do more here, you might want to extract most of that code into a separate method which just takes a string, then create an action which would call that method.)
Are you sure you want to close the serial port as soon as the first line has been received?
You can chage your sp_DataReceived method as,
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(500);
SerialPort sp = (SerialPort)sender;
string data = sp.ReadLine();
this.BeginInvoke(new SetTextDeleg(si_DataReceived), new object[] { data });
sp.Close();
}
and remove the sp.Close(); from si_DataReceived method.
If you want to have a Serial port value in your si_DataReceived method,
you should pass it there:
// First, add port into your delegate
private delegate void SetTextDeleg(SerialPort port, string text);
...
/* HELP START */
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(500);
SerialPort sp = (SerialPort) sender; // <- Obtain the serial port
string data = sp.ReadLine();
// Pass the serial port into si_DataReceived: SetTextDeleg(sp, ...
this.BeginInvoke(new SetTextDeleg(sp, si_DataReceived), new object[] { data });
}
// "SerialPort sp" is added
private void si_DataReceived(SerialPort sp, string data) {
String retorno = data.Trim();
MessageBox.Show(retorno);
// Fecha a porta após pegar o retorno
sp.Close();
}
/* HELP END */
See also:
http://msdn.microsoft.com/library/system.io.ports.serialport.datareceived.aspx