阅读:3176回复:7
TdiBuildSend 函数为何发送效率很低啊,没有socket 的send快
我在驱动下使用TdiBuildSend,发送一个256k 的包需要700ms
而socket的send很快的不到10ms或者更低,不知道需要做什么的处理,才可以提高它的效率阿 |
|
最新喜欢:hongsi... |
驱动老牛
|
沙发#
发布于:2005-05-25 09:33
我在驱动下使用TdiBuildSend,发送一个256k 的包需要700ms 肯定是你实现得有问题,TDI是很快得,我在10M网络下测试得速度能达到7、8MBPS |
|
板凳#
发布于:2005-05-25 10:59
zhangshengyu你可不可以把你的那个发送的代码贴在上面阿,我看看到底是那里出了问题,但我接受可以很快。我现在比较郁闷,呵呵
谢谢 |
|
驱动老牛
|
地板#
发布于:2005-05-25 12:17
zhangshengyu你可不可以把你的那个发送的代码贴在上面阿,我看看到底是那里出了问题,但我接受可以很快。我现在比较郁闷,呵呵 你可以把你的代码贴出来分析一下 |
|
地下室#
发布于:2005-05-25 19:39
引用---我在10M网络下测试得速度能达到7、8MBPS
我想知道你是如何测试的,我测试过3个tdi的代码,都没有这么多 发送都很慢,但接受很快。下面是我的代码。 NTSTATUS TDIClnPerformSends( pTDIClientExtension pDevExt, PFILE_OBJECT pConnFileObj, pTDIClnReqElem pReqElem, // Address of request-element array. PULONG pUlKernelSent ) { PVOID databuf; databuf = ExAllocatePool(NonPagedPool,256*1024); NTSTATUS status; SectorRequestPackage pRequestPackage; LARGE_INTEGER PerformanceFrequency; LARGE_INTEGER dueTimeEnd; LARGE_INTEGER dueTimeBegin; pRequestPackage.dwBeginSetorOffset = 1024; pRequestPackage.dwTotalByetes = 256*1024; pRequestPackage.dwType = 3; pRequestPackage.dwUserID = 0x00; memset(databuf,\'z\',256*1024); status = STATUS_SUCCESS; status = TDIClnSend(pConnFileObj, pDevExt->pTcpDevObj, &pRequestPackage, 16 ); if (!NT_SUCCESS(status)) goto done; dueTimeBegin=KeQueryPerformanceCounter(&PerformanceFrequency ); status = TDIClnSend(pConnFileObj, pDevExt->pTcpDevObj, databuf, 256*1024 ); if (!NT_SUCCESS(status)) goto done; dueTimeEnd=KeQueryPerformanceCounter(&PerformanceFrequency ); DbgPrint((\"Send Time take ************** %d\\n\",(dueTimeEnd.QuadPart-dueTimeBegin.QuadPart)*1000000/PerformanceFrequency.QuadPart)); // End \'do-while\' single-iteration loop. done: if (STATUS_SUCCESS!=status) { DbgPrint((JADrvNm \" \" JADrvRtnsName \".TDIClnPerformSends: Ending status = %lx\\n\", status)); } ExFreePool(databuf); return status; } NTSTATUS TDIClnSend( PFILE_OBJECT pConnFileObj, // Connection (endpoint) file object. PDEVICE_OBJECT pTcpDevObj, // TDI driver\'s device object. PVOID pSendBfr, // Send buffer address. ULONG Length ) { NTSTATUS status; KEVENT SendEvent; // Used to await completion of Send Irp. IO_STATUS_BLOCK IoStatus; EXCEPTION_POINTERS * pExceptionInfo; ULONG lclExceptionCode; PVOID lclExceptionAddr; // DbgPrint((JADrvNm \" \" JADrvRtnsName \".TDIClnSend: Entered\\n\")); do { // Single-iteration loop, to make possible escape via break. KeInitializeEvent(&SendEvent, NotificationEvent, FALSE); PIRP pIrp = // Get an Irp for internal device ioctl. TdiBuildInternalDeviceControlIrp(TDI_SEND, // Type of Irp. pTcpDevObj, // TDI driver\'s device object. pConnFileObj, // Connection (endpoint) file object. &SendEvent, // Event to be signalled when Irp completes. &IoStatus ); if (NULL==pIrp) { status = STATUS_INSUFFICIENT_RESOURCES; break; } PMDL pMdl = IoAllocateMdl(pSendBfr, Length, FALSE, FALSE, pIrp); if (NULL==pMdl) { status = STATUS_INSUFFICIENT_RESOURCES; break; } _try { MmProbeAndLockPages(pMdl, // (Try to) fix buffer. KernelMode, IoModifyAccess ); } _except( pExceptionInfo = GetExceptionInformation(), lclExceptionCode = pExceptionInfo->ExceptionRecord->ExceptionCode, lclExceptionAddr = pExceptionInfo->ExceptionRecord->ExceptionAddress, EXCEPTION_EXECUTE_HANDLER ) { DbgPrint((JADrvNm \" \" JADrvRtnsName \".TDIClnSend: MmProbeAndLockPages() failed. Error = 0x%08x at 0x%08x\\n\", lclExceptionCode, lclExceptionAddr)); status = lclExceptionCode; goto done; } 发送的代码如下: TdiBuildSend(pIrp, pTcpDevObj, // TDI driver\'s device object. pConnFileObj, // Connection (endpoint) file object. NULL, // I/O completion routine. NULL, // Context for I/O completion routine. pMdl, // MDL address. 0, // Flags. 0 => send as normal TSDU. Length // Length of buffer mapped by MDL. ); status = IoCallDriver(pTcpDevObj, pIrp); if (STATUS_PENDING==status) // Have to wait on this Irp? KeWaitForSingleObject(&SendEvent, Executive, KernelMode, FALSE, 0); if ( ( // Problem from IoCallDriver()? STATUS_SUCCESS!=status && STATUS_PENDING!=status ) || ( // Problem discovered in completion? STATUS_PENDING==status && 0!=IoStatus.Status ) ) { // Note: If problem was in IoCallDriver(), IoStatus.Status probably won\'t be meaningful. DbgPrint((JADrvNm \" \" JADrvRtnsName \".TDIClnSend: Problem in IoCallDriver(). status = 0x%08x, IoStatus.Status = 0x%08x\\n\", STATUS_PENDING==status ? 0 : status , IoStatus.Status)); } } while(0); // End \'do-while\' single-iteration loop. status = ((STATUS_SUCCESS==status) || (STATUS_PENDING==status)) ? IoStatus.Status : status; done: return status; } 工程文件见胡建 // |
|
|
5楼#
发布于:2005-05-25 19:44
Nagle will not help here. TDI_SEND waits for all ACKs to arrive from the other side.
This is because TCPIP does not do send buffering (AFD does it), and, after TDI_SEND is complete, the buffer is no more known to TCP, so it will not be able to run retransmits. 这是我在网上看到的 |
|
驱动老牛
|
6楼#
发布于:2005-05-26 11:21
if (STATUS_PENDING==status) // Have to wait on this Irp? 你是这样用的,那你得保证另一方能够足够快地接收到数据 因为这个需要在接收方接收到数据才会返回。 |
|
7楼#
发布于:2005-05-26 21:45
谢谢你啊,问题我找到了。
|
|