gongbin_net
驱动牛犊
驱动牛犊
  • 注册日期2003-06-18
  • 最后登录2005-06-07
  • 粉丝1
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3176回复:7

TdiBuildSend 函数为何发送效率很低啊,没有socket 的send快

楼主#
更多 发布于:2005-05-24 20:55
我在驱动下使用TdiBuildSend,发送一个256k 的包需要700ms
而socket的send很快的不到10ms或者更低,不知道需要做什么的处理,才可以提高它的效率阿

最新喜欢:

hongsinghongsi...
zhangshengyu
驱动老牛
驱动老牛
  • 注册日期2003-10-03
  • 最后登录2016-07-26
  • 粉丝0
  • 关注0
  • 积分792分
  • 威望696点
  • 贡献值41点
  • 好评度499点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2005-05-25 09:33
我在驱动下使用TdiBuildSend,发送一个256k 的包需要700ms
而socket的send很快的不到10ms或者更低,不知道需要做什么的处理,才可以提高它的效率阿

肯定是你实现得有问题,TDI是很快得,我在10M网络下测试得速度能达到7、8MBPS
---内核开发合作或提供基础技术服务QQ:22863668 ---
gongbin_net
驱动牛犊
驱动牛犊
  • 注册日期2003-06-18
  • 最后登录2005-06-07
  • 粉丝1
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-05-25 10:59
zhangshengyu你可不可以把你的那个发送的代码贴在上面阿,我看看到底是那里出了问题,但我接受可以很快。我现在比较郁闷,呵呵
谢谢
zhangshengyu
驱动老牛
驱动老牛
  • 注册日期2003-10-03
  • 最后登录2016-07-26
  • 粉丝0
  • 关注0
  • 积分792分
  • 威望696点
  • 贡献值41点
  • 好评度499点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2005-05-25 12:17
zhangshengyu你可不可以把你的那个发送的代码贴在上面阿,我看看到底是那里出了问题,但我接受可以很快。我现在比较郁闷,呵呵
谢谢

你可以把你的代码贴出来分析一下
---内核开发合作或提供基础技术服务QQ:22863668 ---
gongbin_net
驱动牛犊
驱动牛犊
  • 注册日期2003-06-18
  • 最后登录2005-06-07
  • 粉丝1
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于: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;
}        

工程文件见胡建
                                             //
附件名称/大小 下载次数 最后更新
2005-05-25_tdi2.rar (3188KB)  106
gongbin_net
驱动牛犊
驱动牛犊
  • 注册日期2003-06-18
  • 最后登录2005-06-07
  • 粉丝1
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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.

这是我在网上看到的
zhangshengyu
驱动老牛
驱动老牛
  • 注册日期2003-10-03
  • 最后登录2016-07-26
  • 粉丝0
  • 关注0
  • 积分792分
  • 威望696点
  • 贡献值41点
  • 好评度499点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2005-05-26 11:21
if (STATUS_PENDING==status) // Have to wait on this Irp?
KeWaitForSingleObject(&SendEvent, Executive, KernelMode, FALSE, 0);

你是这样用的,那你得保证另一方能够足够快地接收到数据
因为这个需要在接收方接收到数据才会返回。

---内核开发合作或提供基础技术服务QQ:22863668 ---
gongbin_net
驱动牛犊
驱动牛犊
  • 注册日期2003-06-18
  • 最后登录2005-06-07
  • 粉丝1
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2005-05-26 21:45
谢谢你啊,问题我找到了。
游客

返回顶部