首页
社区
课程
招聘
[旧帖] [求助]HttpDisk的TDI_SEND效率十分低下,求大牛帮忙指点明津(这个问题困扰我好几天了) 0.00雪花
发表于: 2013-11-8 11:23 5318

[旧帖] [求助]HttpDisk的TDI_SEND效率十分低下,求大牛帮忙指点明津(这个问题困扰我好几天了) 0.00雪花

2013-11-8 11:23
5318
最近再做一个基于TDI的内核通讯,参考了HttpDisk这份代码

但是发现TDI_SEND的效率十分低下(20K/s),TDI_RECEIVE还可以接受(10M/s)

不知道为什么,求指点, 给点思路也行

下载地址:
http://www.acc.umu.se/~bosse

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 558
活跃值: (73)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
别沉啊? 大家给点思路吧
2013-11-8 15:43
0
雪    币: 7885
活跃值: (2285)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
楼主呀,我还差2个kx,才够50kx,跪求2个kx呀。
2013-11-9 23:27
0
雪    币: 558
活跃值: (73)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
今天早上过来又试了一下,还是没有解决,谁给点思路吧
2013-11-11 11:07
0
雪    币: 558
活跃值: (73)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
发现一个新的情况,刚在 Win7下面尝试了一下,发现无论读写,速度都很快

XP下面还是很慢,这样就奇怪了,看起来跟操作系统有点关系
2013-11-11 11:14
0
雪    币: 558
活跃值: (73)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
终于找到原因了,是因为Nagle算法。

    TCP在发送数据时,会先把数据存到内部的一个Buffer里面,然后跟下次send的数据进行合并,当大于一个阀值时,数据才真正send的出去。

    当然这里有一个超时处理,如果在一定时间内(大约是40ms),没有收集到足够的数据,那么,也会发送出去。

所以,解决方法有两个:

1. 采用”send-recv-send-recv“的模型

也就是说,两个连续的send之间,必须插入一次 recv 请求,这样在recv的时候,TCP返回了对端的ACK确认,这样 send 请求得以继续

2. 在内核中禁用”Nagle“算法

折腾了两天,尝试了很多代码,都没有结果。

#include <tdiinfo.h>

#define IOCTL_TCP_SET_INFORMATION_EX \
            CTL_CODE(FILE_DEVICE_NETWORK, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS)

#define IOCTL_TCP_QUERY_INFORMATION_EX \
            CTL_CODE(FILE_DEVICE_NETWORK, 0, METHOD_NEITHER, FILE_ANY_ACCESS)

#define TL_INSTANCE      0
#define TCP_SOCKET_NODELAY      1

// NoDelay is currently off and the application wants to turn it on.
NTSTATUS TdiSetTcpNoDelay(PFILE_OBJECT connectionFileObject)
{
    PDEVICE_OBJECT  devObj;
    KEVENT          event;
    PIRP            irp;
    IO_STATUS_BLOCK iosb;
    NTSTATUS        status;
    PIO_STACK_LOCATION  StackLocation;

    INT optionValue = TRUE;
    PTCP_REQUEST_SET_INFORMATION_EX setInfoEx = NULL;
    ULONG len = sizeof(TCP_REQUEST_SET_INFORMATION_EX)+sizeof(INT);

    KeInitializeEvent(&event, NotificationEvent, FALSE);
    devObj = IoGetRelatedDeviceObject(connectionFileObject);

    setInfoEx = ExAllocatePoolWithTag(NonPagedPool, len, VDISK_TAG);
    //
    // Initialize the TDI information buffers.
    //
    setInfoEx->ID.toi_entity.tei_entity = CO_TL_ENTITY;
    setInfoEx->ID.toi_entity.tei_instance = TL_INSTANCE;
    setInfoEx->ID.toi_class = INFO_CLASS_PROTOCOL;
    setInfoEx->ID.toi_type = INFO_TYPE_CONNECTION;
    setInfoEx->ID.toi_id = TCP_SOCKET_NODELAY;
    memcpy( setInfoEx->Buffer, &optionValue, sizeof(INT) );
    setInfoEx->BufferSize = sizeof(INT);


    irp = IoBuildDeviceIoControlRequest (
                IOCTL_TCP_SET_INFORMATION_EX,
                devObj,
                setInfoEx,
                len,
                NULL,
                0,
                FALSE,
                &event,
                &iosb);

    if (irp == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    StackLocation = IoGetNextIrpStackLocation( irp );
    StackLocation->FileObject = connectionFileObject;

    status = IoCallDriver(devObj, irp);

    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
        status = iosb.Status;
    }

    KdPrint(("TdiSetInformation status = 0x%x\n", status));

    return NT_SUCCESS(status) ? (ULONG) iosb.Information : status;
}



虽然IoCallDriver的返回值是成功的,但是却没有任何效果,

如果有人知道,如何在内核禁用Nagle算法,还请赐教!先谢谢了
2013-11-12 11:34
0
游客
登录 | 注册 方可回帖
返回
//