Я пытаюсь записать данные в адаптер крана (интерфейс виртуальной сети) через дескриптор файла.Я открыл файл, вызвав «CreateFile» API, и я могу записать данные.Я записываю в файл около 100 байтов данных, которые иногда занимают больше времени, но я не могу понять, что является причиной этой проблемы.
Я не получаю никаких кодов ошибок, и вызов становится успешным,Единственная проблема в том, что это занимает больше времени для завершения.Я записываю данные 100 раз в цикле, и только некоторые говорят, что 10 итераций "WriteFile" вызовы занимают больше времени для завершения , что вызывает некоторую задержку в дальнейшей обработке пакетов.
#include <stdio.h>
#include <pcap.h>
#include <sys/types.h>
#include <ntddndis.h>
#define LINE_LEN 16
#define ETHER_MAX_LEN 65535
#ifdef WIN32
#include <tchar.h>
BOOL LoadNpcapDlls()
{
_TCHAR npcap_dir[512];
UINT len;
len = GetSystemDirectory(npcap_dir, 480);
if (!len) {
fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
return FALSE;
}
_tcscat_s(npcap_dir, 512, _T("\\Npcap"));
if (SetDllDirectory(npcap_dir) == 0) {
fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
return FALSE;
}
return TRUE;
}
#endif
void physical_dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *);
HANDLE hTapAdapter;
pcap_t *port_a;
DWORD WINAPI DataReceiveHandlerThread(LPVOID lpParam)
{
pcap_loop(port_a, 0, physical_dispatcher_handler, NULL);
return 0;
}
#define BUFFERSIZE 65535
CRITICAL_SECTION m_cs;
int main(int argc, char **argv)
{
BOOL bErrorFlag = FALSE;
//Initilize the critical section
InitializeCriticalSection(&m_cs);
printf("\n");
/*if (argc != 2)
{
printf("Usage Error:\tIncorrect number of arguments\n\n");
_tprintf(TEXT("%s <file_name>\n"), argv[0]);
return;
}*/
hTapAdapter = CreateFile("\\\\.\\Global\\{A2AC038D-EBC1-48F9-B507-BB822AE1C393}.tap", // name of the write
GENERIC_READ | GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
OPEN_EXISTING, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hTapAdapter == INVALID_HANDLE_VALUE)
{
//DisplayError(TEXT("CreateFile"));
_tprintf(TEXT("Terminal failure: Unable to open file \"%s\" for write.\n"), argv[1]);
return;
}
DWORD threadIdentifier = 0;
HANDLE threadHandle = CreateThread(
NULL, // default security attributes
0, // use default stack size
DataReceiveHandlerThread, // thread function name
NULL, // argument to thread function
0, // use default creation flags
&threadIdentifier); // returns the thread identifier
// Check the return value for success.
// If CreateThread fails, terminate execution.
// This will automatically clean up threads and memory.
if (threadHandle == NULL)
{
//ErrorHandler(TEXT("CreateThread"));
ExitProcess(3);
}
WaitForSingleObject(threadHandle, INFINITE);
CloseHandle(threadHandle);
return;
}
void physical_dispatcher_handler(u_char *temp1,
const struct pcap_pkthdr *header,
const u_char *pkt_data)
{
u_int i = 0;
/*
* unused variable
*/
(VOID*)temp1;
DWORD dwBytesWritten = 0;
time_t my_time = time(NULL);
// ctime() used to give the present time
printf("Data received in port A - %s", ctime(&my_time));
// Lock the Critical section
EnterCriticalSection(&m_cs);
BOOL bErrorFlag = WriteFile(
hTapAdapter, // open file handle
pkt_data, // start of data to write
header->len, // number of bytes to write
&dwBytesWritten, // number of bytes that were written
NULL); // no overlapped structure
if (FALSE == bErrorFlag)
{
//DisplayError(TEXT("WriteFile"));
printf("Terminal failure: Unable to write to file.\n");
}
else
{
if (dwBytesWritten != header->len)
{
// This is an error because a synchronous write that results in
// success (WriteFile returns TRUE) should write all data as
// requested. This would not necessarily be the case for
// asynchronous writes.
printf("Error: dwBytesWritten != dwBytesToWrite\n");
}
else
{
time_t my_time = time(NULL);
// ctime() used to give the present time
printf("Data written to tap - %s", ctime(&my_time));
_tprintf(TEXT("Wrote %d bytes to successfully.\n"), dwBytesWritten);
}
}
//Release the Critical section
LeaveCriticalSection(&m_cs);
return;
}