BrianB
July 2nd, 2004, 12:01 AM
I am using a wrapper over the WinPCap libraries, and its working quite well. I wrote a function to save each packet in binary form, directly to a file using write(), and that works great , continuosly.
However, I wrote a second function, to copy the same data out of memory and into a string, and then save the string to file the same way as the other function. The resultant files that are created are identical. here is the problem:
it could be the 2nd packet or the 1000th packet, but eventually I will get this error:
'First chance exception at 0x7C4EA4E1. Exception class EAccessViolation with message 'Access violation at address 0048FB36 in module 'cm_tool.exe'. Write of address 74B36C95'. Process cm_tool.exe (0x7BC)'
It seems to happen when the string is around 900 or so characters in length, but that isnt an absolute either.
Here is the code for the two functions I am refering to :
Code:
//---------------------------------------------------------------------------
int TMainForm::Save_Packet_TEST()
{
//save to file packetid.test.txt
//note: .get_pPacket returns a BYTE aka char pointer
ofstream myFile;
String strFilename = String(apacket.get_packetId()) + ".test.txt";
// copy memory to a string buffer
String strBuffer;
memcpy(strBuffer.c_str(),apacket.get_pPacket(),apacket.get_nLen() );
// open file for binary output
myFile.open (strFilename.c_str(), ios::out | ios::binary);
// write string buffer to file
myFile.write (strBuffer.c_str(),apacket.get_nLen() );
//MessageBox(0,String(strBuffer.Length() ).c_str(), "strBuffer Length", MB_OK);
//MessageBox(0,String(apacket.get_nLen() ).c_str(), "apacket.get_nLen()", MB_OK);
myFile.close();
return 0;
//-------------------------
int TMainForm::Save_Packet_BIN()
{
//save to file packetid.bin.txt
//note: .get_pPacket returns a BYTE aka char pointer
ofstream myFile;
String strFilename = String(apacket.get_packetId()) + ".bin.txt";
//
myFile.open (strFilename.c_str(), ios::out | ios::binary);
//
myFile.write (apacket.get_pPacket(), apacket.get_nLen() );
myFile.close();
return 0;
}
Any suggestions as to how to fix this would be most appreciated.
How would I use TMemoryStream Instead?
Thanks.
Brian
EDIT:
Also, apacket.get_pPacket returns a BYTE pointer to the begining of the packet in memory. get_nLen returns the length of the packet as an int.
This is the event that triggers these functions:
Code:
void __fastcall TMainForm::NetMonitorNewPacket(TJesNetMonitor *Sender)
{
// A packet has been delivered to us - this event is triggered automatically by the NetworkMonitor each time a new
// packet arrives.
// IMPORTANT:
// the network monitor implements a FIFO queue of packets, to allow you to process packets at your leisure
// and not have to handle each one as it comes in.
// This event, if you define it, is triggered each time a new packet comes in.
// If you want to process a packet here, you need to first pop off the next pending (earliest) packet off the queue.
// Often this is the most convenient time to process the packet, but sometimes you will prefer to process packets
// synchronously in your own processing loop, at a specific time/place in your main application loop.
// If you dont choose to pop off a packet here, it will be buffered locally in the network monitor for later processing.
// See JesNetMonitor.h for methods for querying size of local buffer and popping off multiple packets, etc.
// Because we may allow packets to build up with the pause button, we may have multiple packets waiting for us,
// so we loop through them here, and consume all on queue. If we never pause and let packets build up, then
// we will always be processing one packet per call.
while (NetMonitor->get_packetcount()>0)
{
// Get the next packet waiting to be processed (ie the earliest one in the queue).
// Existing apacket memory will be automatically freed and reallocated to hold the new packet.
NetMonitor->GetNextPacket(&apacket);
// If we want to display the new packets in a hex viewer component as they come in:
// the apacket.get_pPacket() call returns a memory pointer to the raw char* packet data.
// the apacket.get_nLen() call return an int which is the number of bytes in the raw packet data.
// PacketViewer->LoadMemory(apacket.get_pPacket(),"A Packet",apacket.get_nLen());
// Display some packet info
static int packetcount=0;
AnsiString packetdatestring;
DateTimeToString(packetdatestring,"HH:MM:SS:ZZ AM/PM",apacket.get_packetdatetime());
AnsiString newcaption;
newcaption=AnsiString("Processed packet number ")+AnsiString(++packetcount)+ " on "+TimeToStr(Time())+" (received at "+packetdatestring+")";
lblPacket->Caption=newcaption;
// Testing
// MainForm->Save_Packet_BIN(); // Working great
MainForm->Save_Packet_HEX(); // crashes
// MainForm->Save_Packet_TEST(); //
} }
However, I wrote a second function, to copy the same data out of memory and into a string, and then save the string to file the same way as the other function. The resultant files that are created are identical. here is the problem:
it could be the 2nd packet or the 1000th packet, but eventually I will get this error:
'First chance exception at 0x7C4EA4E1. Exception class EAccessViolation with message 'Access violation at address 0048FB36 in module 'cm_tool.exe'. Write of address 74B36C95'. Process cm_tool.exe (0x7BC)'
It seems to happen when the string is around 900 or so characters in length, but that isnt an absolute either.
Here is the code for the two functions I am refering to :
Code:
//---------------------------------------------------------------------------
int TMainForm::Save_Packet_TEST()
{
//save to file packetid.test.txt
//note: .get_pPacket returns a BYTE aka char pointer
ofstream myFile;
String strFilename = String(apacket.get_packetId()) + ".test.txt";
// copy memory to a string buffer
String strBuffer;
memcpy(strBuffer.c_str(),apacket.get_pPacket(),apacket.get_nLen() );
// open file for binary output
myFile.open (strFilename.c_str(), ios::out | ios::binary);
// write string buffer to file
myFile.write (strBuffer.c_str(),apacket.get_nLen() );
//MessageBox(0,String(strBuffer.Length() ).c_str(), "strBuffer Length", MB_OK);
//MessageBox(0,String(apacket.get_nLen() ).c_str(), "apacket.get_nLen()", MB_OK);
myFile.close();
return 0;
//-------------------------
int TMainForm::Save_Packet_BIN()
{
//save to file packetid.bin.txt
//note: .get_pPacket returns a BYTE aka char pointer
ofstream myFile;
String strFilename = String(apacket.get_packetId()) + ".bin.txt";
//
myFile.open (strFilename.c_str(), ios::out | ios::binary);
//
myFile.write (apacket.get_pPacket(), apacket.get_nLen() );
myFile.close();
return 0;
}
Any suggestions as to how to fix this would be most appreciated.
How would I use TMemoryStream Instead?
Thanks.
Brian
EDIT:
Also, apacket.get_pPacket returns a BYTE pointer to the begining of the packet in memory. get_nLen returns the length of the packet as an int.
This is the event that triggers these functions:
Code:
void __fastcall TMainForm::NetMonitorNewPacket(TJesNetMonitor *Sender)
{
// A packet has been delivered to us - this event is triggered automatically by the NetworkMonitor each time a new
// packet arrives.
// IMPORTANT:
// the network monitor implements a FIFO queue of packets, to allow you to process packets at your leisure
// and not have to handle each one as it comes in.
// This event, if you define it, is triggered each time a new packet comes in.
// If you want to process a packet here, you need to first pop off the next pending (earliest) packet off the queue.
// Often this is the most convenient time to process the packet, but sometimes you will prefer to process packets
// synchronously in your own processing loop, at a specific time/place in your main application loop.
// If you dont choose to pop off a packet here, it will be buffered locally in the network monitor for later processing.
// See JesNetMonitor.h for methods for querying size of local buffer and popping off multiple packets, etc.
// Because we may allow packets to build up with the pause button, we may have multiple packets waiting for us,
// so we loop through them here, and consume all on queue. If we never pause and let packets build up, then
// we will always be processing one packet per call.
while (NetMonitor->get_packetcount()>0)
{
// Get the next packet waiting to be processed (ie the earliest one in the queue).
// Existing apacket memory will be automatically freed and reallocated to hold the new packet.
NetMonitor->GetNextPacket(&apacket);
// If we want to display the new packets in a hex viewer component as they come in:
// the apacket.get_pPacket() call returns a memory pointer to the raw char* packet data.
// the apacket.get_nLen() call return an int which is the number of bytes in the raw packet data.
// PacketViewer->LoadMemory(apacket.get_pPacket(),"A Packet",apacket.get_nLen());
// Display some packet info
static int packetcount=0;
AnsiString packetdatestring;
DateTimeToString(packetdatestring,"HH:MM:SS:ZZ AM/PM",apacket.get_packetdatetime());
AnsiString newcaption;
newcaption=AnsiString("Processed packet number ")+AnsiString(++packetcount)+ " on "+TimeToStr(Time())+" (received at "+packetdatestring+")";
lblPacket->Caption=newcaption;
// Testing
// MainForm->Save_Packet_BIN(); // Working great
MainForm->Save_Packet_HEX(); // crashes
// MainForm->Save_Packet_TEST(); //
} }