阅读:1363回复:6
再次请教各位,关于读取PACKET时丢失数据的问题。(20 分)
感谢老MO的提示和老胡的文章,现在收到PACKET后给WIN32发送NOFITYEVENT, WIN32 可以读到PACKET了。但是现在的问题是当流量大的时候会丢失数据。我现在用的是BUFFERED_IO,PACKET拷到IRP->ASSOCIATEDIRP->SYSTEMBUFFER,应用程序通过DEVICEIOCONTROL到这里读取数据。请问我如何才能解决这个问题?
谢谢各位! |
|
沙发#
发布于:2002-08-23 23:13
感谢老MO的提示和老胡的文章,现在收到PACKET后给WIN32发送NOFITYEVENT, WIN32 可以读到PACKET了。但是现在的问题是当流量大的时候会丢失数据。我现在用的是BUFFERED_IO,PACKET拷到IRP->ASSOCIATEDIRP->SYSTEMBUFFER,应用程序通过DEVICEIOCONTROL到这里读取数据。请问我如何才能解决这个问题? 可以两面入手: 1。应用层开多线程。 2。驱动层内建一环形的缓冲区。 当然可能还有其他更好的方法!? :) |
|
|
板凳#
发布于:2002-08-23 23:25
谢谢MAGICX,不知我能否将IRP->ASSOCIATEDIRP->SYSTEMBUFFER做成CIRCULAR BUFFER呀?如果问题太愚蠢,请别见笑, 我是新手:-)
|
|
地板#
发布于:2002-08-24 06:18
再将我的问题仔细描述一下:
NDIS_STATUS IOControlHandler ( DWORD ControlCode, PUCHAR pInBuffer, DWORD InputBufferLength, PUCHAR pOutBuffer, DWORD OutputBufferLength, PDWORD pReturnedSize ) { switch ( ControlCode ) { case IOCTL_PIM_GET_VERSION: { *((PDWORD) pOutBuffer) = NDISHK_ETHERNET_BRIDGE; *pReturnedSize = sizeof (DWORD); return NDIS_STATUS_SUCCESS; } case IOCTL_PIM_SET_BRIDGING: { PrF_SetBridgingStatus (*((PDWORD)(pInBuffer))); *pReturnedSize = 0; return NDIS_STATUS_SUCCESS; } case IOCTL_PIM_GET_PACKET: { RtlMoveMemory(pOutBuffer, data1, MAX_ETHER_SIZE*sizeof(unsigned char)); DbgPrint(\"IoControlHandler is : %X%X%X%X%X%X%X%X%X%X%X\\n\", pOutBuffer[0], pOutBuffer[1],pOutBuffer[2],pOutBuffer[3],pOutBuffer[4],pOutBuffer[5],pOutBuffer[6],pOutBuffer[7],pOutBuffer[8],pOutBuffer[9],pOutBuffer[10]); *pReturnedSize = MAX_ETHER_SIZE*sizeof(unsigned char); return NDIS_STATUS_SUCCESS; } } return NDIS_STATUS_NOT_RECOGNIZED; } DISPATCH ROUTINE 里: case IRP_MJ_DEVICE_CONTROL: { pBuffer = ( PUCHAR ) Irp -> AssociatedIrp.SystemBuffer; InputBufferLength = irpStack -> Parameters.DeviceIoControl.InputBufferLength; OutputBufferLength = irpStack -> Parameters.DeviceIoControl.OutputBufferLength; ControlCode = irpStack -> Parameters.DeviceIoControl.IoControlCode; Status = STATUS_SUCCESS; if ( IOControlHandler ( ControlCode, pBuffer, InputBufferLength, pBuffer, OutputBufferLength, &ReturnedSize ) != NDIS_STATUS_SUCCESS ) { Status = STATUS_INVALID_PARAMETER; ReturnedSize = 0; } WIN32程序如下: #include \"stdafx.h\" // Sample class for driver connectivity class CPIMApi { public: // Data members bool m_IsLoadSuccessfully; int m_SizeRet; // Functions bool DrvIoControl ( DWORD dwService, void *BuffIn, int SizeIn, void *BuffOut, int SizeOut, int *SizeRet, LPOVERLAPPED povlp); int GetVersion(); void SetBridgingState (ULONG state); void GetPacket(); void SetUserEvent(); // Construction/destruction CPIMApi(const char * pszFileName = \"NDISHK\" ); ~CPIMApi(); private: // Protected data members OVERLAPPED m_ovlp; HANDLE m_hDrv; public: HANDLE m_hEvent; int k; }; // Constructor besides initialization opens driver CPIMApi::CPIMApi(const char * pszFileName ) { char FullName [ 300 ]; strcpy ( FullName, \"\\\\\\\\.\\\\\" ); strcat ( FullName, pszFileName ); m_IsLoadSuccessfully = FALSE; k = 0; m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hDrv = CreateFile( FullName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE, 0 ); if ( m_hDrv == INVALID_HANDLE_VALUE ) { m_hDrv = CreateFile ( FullName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 ); } if ( m_hDrv == INVALID_HANDLE_VALUE ) { m_ovlp.hEvent = 0; } else { m_ovlp.hEvent = 0; m_ovlp.hEvent = CreateEvent ( 0, TRUE, FALSE, NULL ); if ( m_ovlp.hEvent ) { m_IsLoadSuccessfully = TRUE; } } } // Destructor closes handle to device CPIMApi::~CPIMApi() { if ( m_hDrv != INVALID_HANDLE_VALUE ) { CloseHandle ( m_hDrv ); } if ( m_ovlp.hEvent ) { CloseHandle ( m_ovlp.hEvent ); } } // Wrapper around DeviceIoControl API bool CPIMApi::DrvIoControl(DWORD dwService, void *BuffIn, int SizeIn, void *BuffOut, int SizeOut, int *SizeRet, LPOVERLAPPED povlp) { ULONG Ret = 0; if ( m_hDrv != INVALID_HANDLE_VALUE ) { if(povlp == NULL) Ret = DeviceIoControl ( m_hDrv, dwService, BuffIn, SizeIn, BuffOut, SizeOut, (unsigned long*)SizeRet, &m_ovlp); else Ret = DeviceIoControl ( m_hDrv, dwService, BuffIn, SizeIn, BuffOut, SizeOut, (unsigned long*)SizeRet, povlp); } return Ret?true:false; } // Getting version info function int CPIMApi::GetVersion() { ULONG nDriverAPIVersion = 0xFFFFFFFF; int cbBytesRet =0; bool bIOResult = DrvIoControl( IOCTL_PIM_GET_VERSION, &nDriverAPIVersion, sizeof(ULONG), &nDriverAPIVersion, sizeof(ULONG), &cbBytesRet, // Bytes Returned NULL ); return nDriverAPIVersion; } // Starts bridging interfaces void CPIMApi::SetBridgingState (ULONG state) { int cbBytesRet =0; if (GetVersion() == NDISHK_ETHERNET_BRIDGE) { printf (\"\\nThis version support bridging.\\nStarting....\\n\"); bool bIOResult = DrvIoControl( IOCTL_PIM_SET_BRIDGING, &state, sizeof(ULONG), NULL, 0, &cbBytesRet, // Bytes Returned NULL ); } else { printf (\"\\nThis version of driver does not support ethernet bridging.\\n\"); } } void CPIMApi::GetPacket() { unsigned char v[1515]; unsigned char t[1515]; ULONG cbBytesRet =0; OVERLAPPED overlapped; memset(v, 0, 1515*sizeof(unsigned char)); memset(t, 0, 1515*sizeof(unsigned char)); memset(&overlapped, 0, sizeof(OVERLAPPED)); overlapped.hEvent = CreateEvent( NULL, // pointer to security attributes FALSE, // automatic reset FALSE, // initialize to not signaled NULL ); // pointer to the event-object name // ReadFile( m_hDrv, t, 1515*sizeof(unsigned char), &cbBytesRet, &overlapped); bool bIOResult = DrvIoControl( IOCTL_PIM_GET_PACKET, &v, 1515 * sizeof(unsigned char), &t, 1515 * sizeof(unsigned char), reinterpret_cast<int *>(&cbBytesRet), // Bytes Returned &overlapped ); printf(\"Test value %d is %x%x%x%x%x%x%x%x%x%x%x \\n\", k, t[0], t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9]); k++; } void CPIMApi::SetUserEvent() { int bytesRet; DrvIoControl( IOCTL_PIM_SET_EVENT, &m_hEvent, sizeof(HANDLE), NULL, 0, &bytesRet, NULL); } int main(int argc, char* argv[]) { CPIMApi api; DWORD status; if (api.m_IsLoadSuccessfully) { if (argc == 2) { if (!strcmp(argv[1], \"ON\")) { api.SetBridgingState(1); api.SetUserEvent(); while(1) { status = WaitForSingleObject(api.m_hEvent, INFINITE); if (status == WAIT_ABANDONED || status == WAIT_OBJECT_0 || status == WAIT_TIMEOUT) { printf(\"got event %d %d\\n\", api.k, status); // api.GetPacket(); // api.GetPacket(); api.k++; } } return 0; } if (!strcmp(argv[1], \"OFF\")) { api.SetBridgingState (0); return 0; } } } printf (\"Usage: client OFF|ON\\n OFF - stop bridging \\n ON - start bridging\"); return 0; } 如果在DRIVER里用一CIRCULAR BUFFER,该如何实现?因为我在DRIVER理实际就是将数据拷到SYSTEMBUFFER 里。 谢谢各位。 |
|
地下室#
发布于:2002-08-24 12:54
感谢老MO的提示和老胡的文章,现在收到PACKET后给WIN32发送NOFITYEVENT, WIN32 可以读到PACKET了。但是现在的问题是当流量大的时候会丢失数据。我现在用的是BUFFERED_IO,PACKET拷到IRP->ASSOCIATEDIRP->SYSTEMBUFFER,应用程序通过DEVICEIOCONTROL到这里读取数据。请问我如何才能解决这个问题? 我郁闷,因为很显然你对我的代码误用了, 我写那篇文章是要解释如何用扳手拧一个螺丝, 当然,你用这把扳手订钉子也能钉进去,但是 感觉不会太好吧? |
|
|
5楼#
发布于:2002-08-24 18:52
感谢老MO的提示和老胡的文章,现在收到PACKET后给WIN32发送NOFITYEVENT, WIN32 可以读到PACKET了。但是现在的问题是当流量大的时候会丢失数据。我现在用的是BUFFERED_IO,PACKET拷到IRP->ASSOCIATEDIRP->SYSTEMBUFFER,应用程序通过DEVICEIOCONTROL到这里读取数据。请问我如何才能解决这个问题? 我对这个问题也想弄明白, 为什么你用DEVICEIOCONTROL来读数据呢? 能不能用MajorFunction[IRP_MJ_READ],然后在应用层用 ReadFile来读数据,另外,如果加密数据,有没有必要将数据 传到应用层,在那里加密,再写到核心层呢? |
|
6楼#
发布于:2002-08-24 19:03
[quote]感谢老MO的提示和老胡的文章,现在收到PACKET后给WIN32发送NOFITYEVENT, WIN32 可以读到PACKET了。但是现在的问题是当流量大的时候会丢失数据。我现在用的是BUFFERED_IO,PACKET拷到IRP->ASSOCIATEDIRP->SYSTEMBUFFER,应用程序通过DEVICEIOCONTROL到这里读取数据。请问我如何才能解决这个问题? 我对这个问题也想弄明白, 为什么你用DEVICEIOCONTROL来读数据呢? 能不能用MajorFunction[IRP_MJ_READ],然后在应用层用 ReadFile来读数据,另外,如果加密数据,有没有必要将数据 传到应用层,在那里加密,再写到核心层呢? [/quote] 应该只是个例子吧! 不必如此的细哦。。。。。。 :) |
|
|