I am using PcapDotNet DLL's in my application, and I am encountering a problem:
My application takes a PCap file (Wireshark file) and sends the packets to the network card. If I send a file or files many times (usually ~500 times), my application crashes with the error Failed opening file C:\file.pcap. I tried to ask in the project forum, but the developer isn't there permanently, so maybe someone else could help me here.
The error cause is here in inputCommunicator, and when the error occurs, this object value is null. Please note that this happens only after a few hundred iterations (approximately 500).
code:
using (PacketCommunicator inputCommunicator = selectedInputDevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000))
{
using (mOutputCommunicator = selectedOutputDevice.Open(100, PacketDeviceOpenAttributes.Promiscuous, 1000))
{
while (inputCommunicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok && _isStop) //fill the buffer with the packets from the file
{
using (PacketSendBuffer mSendBuffer = new PacketSendBuffer((uint)packet.Length * 4))
{
else if (packet != null)
{
lastTime = packet.Timestamp;
mSendBuffer.Enqueue(packet); //put the packet in the buffer
}
mOutputCommunicator.Transmit(mSendBuffer, _isBurst); //send the packet
_numberOfSendPackets++;
}
}
}
}
This is a bug in WinPcap.
For the details, see http://www.winpcap.org/pipermail/winpcap-bugs/2012-December/001547.html
Related
I made a very simple WindowsService that waits data from an UDP port trough WiFi and once received them, it writes them in a txt file (as many examples/tutorials that you can find on the web). I anticipate I usually develop WIndowsForm. The Service choise arises from the need to have a background process that always works, without showing anything to the user... the latter will check the file with the data saved only when needed.
Through the AppConfig.xml file a set the log path and file name and when I run it through VisualStudio no problems appear, as well when I install it (through prompt cmd) on my PC (where I developed it). Everything seems to work properly!
When I tried to install and run it on others PC (included the one where it's supposed to work), the WindowsService has been correctly installed and looked like to work but actually doesn't write on the file (first strange behaviour).
I think is something related to permission.
The account set in the installer is the LocalSystem.
I tried to compile again my project but with the log path hard coded and equals to the directory where the WindowsService.exe is placed but it works only when I run it from VS. When I run it from Services it has the same behaviour seen before: it starts without any error but it doesn't write to the file (second strange behaviour). Obv it doesn't work also to the other PC.
In both cases (write or not) the output in the Process Monitor is the same.Fail to write and OK
Finally, everytime I modify my code and I run it through VS, my Avast antivirus initially blocks the debug because it has to check the .exe file first. Then, the process starts correctly. It's like this only the first time after a change in the code (and so a change in the .exe). This doesn't happen, for example, when I develop and execute WindowsForm...
I'm blocked here from weeks, I hope so much in your help!
Many thanks in advance fot your time.
SB
Code below.
I search for a string in the text file (workbench station).
If this string is already present, I update its associated counter value.
If this string is not present, I added a new line with the new workbench and its counter value.
// Save data received in text file
using (StreamReader sr = new StreamReader(Path.Combine(docPath, fileName)))
{
lineToFind = bancoDiLavoro.Insert(bancoDiLavoro.Length, receiveBytes[0].ToString());
Console.Write("Line to find in text file: ");
Console.WriteLine(lineToFind);
allLines = File.ReadAllLines(Path.Combine(docPath, fileName));
lineNumber = 0;
while (allLines.Length != 0)
{
line = sr.ReadLine();
lineNumber = lineNumber + 1;
try
{
if (line != null)
{
if (line.Contains(lineToFind))
{
sr.Close();
lineFound = true;
allLines[lineNumber - 1] = lineToFind.Insert(lineToFind.Length, "\tConteggio: " + count.ToString() + "\t");
File.WriteAllLines(Path.Combine(docPath, fileName), allLines);
break;
}
}
else
{
Console.WriteLine("Empty line found.");
lineFound = false;
break;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
lineFound = false;
}
}
if (lineFound == false)
{
// Workbench not found: a new workstation has been added
sr.Close();
File.AppendAllText(Path.Combine(docPath, fileName), lineToFind);
File.AppendAllText(Path.Combine(docPath, fileName), "\tConteggio: ");
File.AppendAllText(Path.Combine(docPath, fileName), count.ToString() + "\n");
Thread.Sleep(100);
}
}
[UPDATE]
I've been able to add the EventLog to my service and on the PCs where the service doesn't work, seem that the data are not received on UDP port (even if the port is correctly "opened"). I have to work on this now...
The service remains blocked here:
Byte[] receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
try
{
//Creates a UdpClient for reading incoming data.
UdpClient receivingUdpClient = new UdpClient(UDPport);
//Creates an IPEndPoint to record the IP Address and port number of the sender.
// The IPEndPoint will allow you to read datagrams sent from any source.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
eventLog1.WriteEntry("UDP port opened.");
while (waitForPacket == true)
{
// Blocks until a message returns on this socket from a remote host.
Byte[] receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
Console.Write("Workbench: ");
Console.Write(receiveBytes[0]);
Console.Write(", count: ");
Console.WriteLine(receiveBytes[1]);
Console.WriteLine("This message was sent from " +
RemoteIpEndPoint.Address.ToString() +
" on their port number " +
RemoteIpEndPoint.Port.ToString());
eventLog1.WriteEntry("data received.");
// Continues with the data writing...
For a project, I have to communicate with a Raspberry Pi Zero from a UWP-APP via TCP. Because both, the Raspberry and the computer with the interface, have got a private IP, I have to use a server to forward messages from one client to the other one. This part already works but now my problem is that I have to implement video streaming from the Raspberry to the UWP-APP.
Because my partner is in charge of creating and designing the UWP-APP, I have made myself a little Test-Interface with WindowsForms. I have tried several techniques like Netcat the video output over the server to the client or direct TCP-streaming with raspivid, but the best solution so far is the one I found in this project here. But instead of using the Eneter.Messaging-library I use my own class for communication with TcpClients.
I use mono to run my C# script on the Raspberry and the code to stream the Video looks like this:
while (true)
{
//Wait with streaming until the Interface is connected
while (!RemoteDeviceConnected || VideoStreamPaused)
{
Thread.Sleep(500);
}
//Check if Raspivid-Process is already running
if(!Array.Exists(Process.GetProcesses(), p => p.ProcessName.Contains("raspivid")))
raspivid.Start();
Thread.Sleep(2000);
VideoData = new byte[VideoDataLength];
try
{
while (await raspivid.StandardOutput.BaseStream.ReadAsync(VideoData, 0, VideoDataLength) != -1 && !VideoChannelToken.IsCancellationRequested && RemoteDeviceConnected && !VideoStreamPaused)
{
// Send captured data to connected clients.
VideoConnection.SendByteArray(VideoData, VideoDataLength);
}
raspivid.Kill();
Console.WriteLine("Raspivid killed");
}
catch(ObjectDisposedException)
{
}
}
Basically, this method just reads the h264 data from the Standard-Output-Stream of the raspivid process in chunks and sends it to the server.
The next method runs on the server and just forwards the byte array to the connected interface-client.
while (RCVVideo[id].Connected)
{
await RCVVideo[id].stream.ReadAsync(VideoData, 0, VideoDataLength);
if (IFVideo[id] != null && IFVideo[id].Connected == true)
{
IFVideo[id].SendByteArray(VideoData, VideoDataLength);
}
}
SendByteArray() uses the NetworkStream.Write() Method.
On the interface, I write the received byte[] to a named pipe, to which the VLC-Control connects to:
while (VideoConnection.Connected)
{
await VideoConnection.stream.ReadAsync(VideoData, 0, VideoDataLength);
if(VideoPipe.IsConnected)
{
VideoPipe.Write(VideoData, 0, VideoDataLength);
}
}
Following code initializes the pipe-server:
// Open pipe that will be read by VLC.
VideoPipe = new NamedPipeServerStream(#"\raspipipe",
PipeDirection.Out, 1,
PipeTransmissionMode.Byte,
PipeOptions.WriteThrough, 0, 10000);
And for VLC:
LibVLC libVLC = new LibVLC();
videoView1.MediaPlayer = new MediaPlayer(libVLC);
videoView1.MediaPlayer.Play(new Media(libVLC, #"stream/h264://\\\.\pipe\raspipipe", FromType.FromLocation));
videoView1.MediaPlayer.EnableHardwareDecoding = true;
videoView1.MediaPlayer.FileCaching = 0;
videoView1.MediaPlayer.NetworkCaching = 300;
This works fine on the Windowsforms-App and I can get the delay down to 2 or 3 seconds (It should be better in the end but it is acceptable). But on the UWP-App I can't get it to work even after adding /LOCAL/ to the pipe name. It shows that the VLC-Control connects to the pipe, and I can see that data is written to the pipe but it doesn't display video.
So my question is:
How can I get this to work with the VLC-Control (LibVLCSharp) in UWP? Am I missing something fundamental?
Or is there even a better way to stream the video in this case?
I have researched a bit on the UWP-MediaPlayerElement to but I can't find a way to get my byte[] into it.
First of all, thank you for your quick responses and interesting ideas!
I took a look into Desktop Bridge but it is not really what I wanted, because my colleague has already put in a lot of effort to design the UWP-APP and my Windows-Form is just a botch to try things out.
But the thing that really worked for me was StreamMediaInput . I have no idea how I missed this before. This way I just passed my NetworkStream directly to the MediaPlayer without using a Named-Pipe.
LibVLC libVLC = new LibVLC();
videoView1.MediaPlayer = new MediaPlayer(libVLC);
Media streamMedia = new Media(libVLC, new StreamMediaInput(Client.Channels.VideoConnection.stream), ":demux=h264");
videoView1.MediaPlayer.EnableHardwareDecoding = true;
videoView1.MediaPlayer.FileCaching = 0;
videoView1.MediaPlayer.NetworkCaching = 500;
videoView1.MediaPlayer.Play(streamMedia);
This solution is now working for me both, in UWP and in Windows-Forms.
Okay so I am stuck for almost 20 days now in the same problem of a serial communication device. I have a hardware sensor which read tags and returns the tag code number on every read through serial com port 1 or 3.Any of these I use doesn't matter. I am using a program I wrote in c# to play with the incoming data.
Now problem is that if forexample:
my sensor reads tag with code "e2 0 10 1 83 10 1 23 7 0 d0 c0 1 be"
It will not read this tag again unless I switch of the sensor and turn it on again (Power reset) . So I can't figure out how to make my sensor forget all the data it read till I closed the port. ANY ONE CAN HELP PLEASE I AM DESPERATE NOW
Some one told me that we need to write to device with some commands but he didn't know more than that.
Here is the current code:
void IntializeSensor()
{
try
{
if (mySerialPort==null)
{
mySerialPort = new SerialPort("COM3");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.ReadTimeout = 2000;
mySerialPort.Handshake = Handshake.None;
LoglistBox.Items.Add("--Port Intilalized at COM1--");
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
void OpenPort()
{
try
{
str = "";
if (mySerialPort.IsOpen)
{
ClosePort();
Thread.Sleep(6000);
}
mySerialPort.Open();
LoglistBox.Items.Add("--Port Opened at COM1 Success--");
}
catch (Exception ex)
{
LoglistBox.Items.Add("--Port Opened Failed--Error: "+ex.Message);
}
}
void ClosePort()
{
try
{
mySerialPort.Write("ABCABCABCABCABC");
mySerialPort.DiscardInBuffer();
mySerialPort.DiscardOutBuffer();
mySerialPort.Dispose();
mySerialPort.Close();
LoglistBox.Items.Add("--Port Closed at COM1 Success--");
}
catch (Exception ex)
{
LoglistBox.Items.Add("--Port Closed Failed--Error: " + ex.Message);
MessageBox.Show(ex.Message);
}
}
private void DataReceivedHandler(object sender,SerialDataReceivedEventArgs e)
{
try
{
if (e.EventType != SerialData.Chars) return;
SerialPort COMPort = (SerialPort)sender;
int bytes = COMPort.BytesToRead;
//create a byte array to hold the awaiting data
byte[] comBuffer = new byte[bytes];
//read the data and store it
COMPort.Read(comBuffer, 0, bytes);
// System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
str = ByteArrayToHexString(comBuffer);
holdfirstvalue += str;
//str = str +" "+ str;
//MessageBox.Show("after concat "+str);
if (str.Contains("FF") || str.Contains("F F") || str.Contains("F"))
{
SetText(holdfirstvalue.ToString());// ONE TAG CODE SENT TO BE SET IN LIST
str = "";
holdfirstvalue = "";
}
}
catch (Exception ex)
{
// LoglistBox.Items.Add("--Port Opened Failed--Error: " + ex.InnerException);
MessageBox.Show(ex.Message+" "+ex.InnerException);
}
}
As I understood from your comments, even the program that is shipped with it does not read the same bar-code twice in a row. Am I right?
To me it seems that "the tag reader manufacturer" may have put that mechanism intentionally to prevent user mistakenly scan an item twice at check-out. because it happens a lot that a same stays on the scanner or be crossed against the scanner couple of times when moving things around.
Unless you have access to the scanner Firmware and are able to make changes yourself, I'd say contact the manufacturer. I would contact the manufacturer and ask about this directly. There should be a command that tells the scanner to "Get out of lock mode and restart scanning again" for the special case of scanning a same item several times (e.g. buying multiple similar things.)
They should provide you with a manual with the list of all the commands you can send to your device and you use this commands to build up your system.
One more thing to try! can you scope out your serial port using "Real Term" or any other terminal monitoring application to see if the scanner sends the code to the PC after you scan the same item again or not? This helps you to isolate the problem to make sure if it is the Scanner Firmware or the desktop software. (it seems to me that it is the scanner Firmware ignoring the item because you say it works fine when you reset it)
edit: also I see you are reading your serial port based on DataREadyEvent, again, if it was me, I would add another thread with a very short delay say 20ms or 50ms to keep reading the serial port constantly. there are plenty of examples on how to implement this on the net, one simple and quick way of this is described here:
Read com ports using threading in c#
Hope it helps.
Ok so I finally found the code in hex which actually resets the sensor.
So to help anyone out there who bought Middle Range UHF RFID Reader or any type of this model.
What we did is we hacked into the wires of serial port by soldering copper wire on data pins. Then we attached the other end of those copper wires to my laptop and used the terminal reader "Putty" to see what is actually being sent by the PC to the Reader on RESET HEAD button click.
This way we found the hex code , converted it to byte array and here is the C# code to write it to reader device by serial port and resets the device:
{
mySerialPort.Open();
byte[] bytesToSend = StringToByteArray("A00265F9");// correct command to reset READER
mySerialPort.Write(bytesToSend, 0, 4);
}
public static byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
I've written a simple windows service to watch a folder and run relog (the windows tool to export data from binary perf mon files) on any files that arrive.
When I run it from my c# process (using System.Diagnostics.Process.Start()) I get:
Error:
Unable to open the specified log file.
But if I copy and paste the command into a console window it works fine.
I've looked all over the net but everything seems to point to a corrupt file, which I know is not the case as I can import perfectly when running manually.
Any help greatly appreciated.
If you are using FileSystemWatcher to monitor for files it will fire the created event before the file is completely written to disk, this would cause the kind of error from relog about being unable to "open" a file since it might still be locked and technically corrupt as far as it's concerned.
I've written the following helper method that I always use in conjunction with FileSystemWatcher to wait for a file to be completely written and ready for processing after a created event and will also kick out after a timeout:
public static bool WaitForFileLock(string path, int timeInSeconds)
{
bool fileReady = false;
int num = 0;
while (!fileReady)
{
if (!File.Exists(path))
{
return false;
}
try
{
using (File.OpenRead(path))
{
fileReady = true;
}
}
catch (Exception)
{
num++;
if (num >= timeInSeconds)
{
fileReady = false;
}
else
{
Thread.Sleep(1000);
}
}
}
return fileReady;
}
I have been working on an IMAP client to get emails from Gmail. My application worked fine until about an hour ago, when attachments stopped being retrieved.
The connection and messaging is being handled by imapX.
Connection is OKAY
Login is OKAY
Getting folders is OKAY
Getting messages is OKAY
At this point attachments.Count == 0. It was working earlier this afternoon so I wonder if I have been over testing and Google have blacklisted my computer for a while? Does anyone know if this is the case? - Been running perhaps once every 5-10 minutes, maybe more at times so this could be a plausible issue.
I have attempted to send a new email with a totally new file and it still does not see the attachment (but it is (always) seeing the messages themselves).
Can any anyone shine some light on this issue?
EDIT : Header includes the following tag {[X-MS-Has-Attach, yes]}
EDIT (code) :
private void PollMailFolders(object state)
{
try
{
if(_imapClient == null || !_imapClient.IsConnected)
_imapClient = new ImapClient(_config.Server, _config.Port, true);
if (_imapClient.Connection())
{
if(!_imapClient.IsLogined)
_imapClient.LogIn(_config.Username, _config.Password);
string dateSearch = string.Format(
"SINCE {0:d-MMM-yyyy}{1}", DateTime.Today.AddDays(-_config.HistoryOnStartupDays),
_isFirstTime ? "" : " UNSEEN");
_isFirstTime = false;
foreach (Folder folder in _imapClient.Folders["SSForecasts"].SubFolder)
{
var messages = _imapClient.Folders[folder.Name].Search(dateSearch, false);
foreach (Message m in messages)
{
m.Process();
foreach (var a in m.Attachments)
{
SendDataToParser(_encoding.GetString(a.FileData), folder.Name);
}
m.SetFlag(ImapFlags.SEEN);
}
}
}
}
catch(Exception e)
{
_diagnostics.Logger.ErrorFormat("Error in PollMailFolders: {0}", e);
}
}
I have produced a work around which allows me to get the attachment data. Not the solution I had in mind, though it does work.
Simple filename extension check followed by a conversion of the message data.
BTW: _encoding = Encoding.GetEncoding(1252);
if (bodyPart.ContentFilename.EndsWith(".csv"))
{
return _encoding.GetString(Convert.FromBase64String(bodyPart.ContentStream));
}