UDP的发送效率和什么因素有关呢?

直观觉得,UDP的切包长越大,应该发送效率越高(最长为65536)。可是依据实际測试和在网上查到的资料的结果,包长度为1024为发送效率最高。

这样的结果让人感到疑惑,为什么是1024这样的奇怪的值呢?为什么不是MTU(最小发送单元)的长度(即1500-28)呢?

后来调查发现,Windows的网络底层,默认UDP分片长度为1024时,走的是高速通道模式,详细如何的高速通道?没有再继续深入研究。

通过改动以下的注冊表能够加大1024.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Parameters\FastSendDatagramThreshold

而且须要改动网卡注冊表的MTU与上面的值一致,详细注冊表项例如以下所看到的:

HKEY_LOCAL_MACHINE\\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\MTU

改动以上注冊表值的演示样例代码:

// 改动本地UDP包发送长度并依据网络MTU确定实际UDP发送的包长度
// <span style="font-family: Arial, Helvetica, sans-serif;">lenPacket【out】:包长度,</span><span style="font-family: Arial, Helvetica, sans-serif;">bIsToRestartComputer【out】:是否重新启动计算机(当改动了注冊表,则须要重新启动有效)</span>
<pre name="code" class="cpp"><span style="font-family:Arial, Helvetica, sans-serif;">// 返回:TRUE(成功),FALSE(失败)</span>

BOOL SetMaxEfficencyUDPPacketLength(INT &lenPacket, BOOL &bIsToRestartComputer)
{
// 初始化
lenPacket = MAX_SUPER_DISPLAY_UDP_LENGTH;
// 设置【HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Parameters】
// 加入FastSendDatagramThreshold=1500
if (!CUtil::IsKeyExist(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters"),
_T("FastSendDatagramThreshold")))
{
// 假设写入失败,则依照发送
if (!CUtil::WriteKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters"),
_T("FastSendDatagramThreshold"), MTU_DEFAULT))
{
lenPacket = NOT_SET_FAST_SEND_DATAGRAME_UDP_LENGTH;
return FALSE;
}
bIsToRestartComputer = TRUE;
}
// 校验值
else
{
INT iValue = 0;
// 获取键值
if (CUtil::ReadKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters"),
_T("FastSendDatagramThreshold"), iValue))
{
// 假设键值不是MTU默认值,则改动
if (iValue != MTU_DEFAULT)
{
// 假设写入失败,则依照发送
if (!CUtil::WriteKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters"),
_T("FastSendDatagramThreshold"), MTU_DEFAULT))
{
lenPacket = NOT_SET_FAST_SEND_DATAGRAME_UDP_LENGTH;
return FALSE;
}
bIsToRestartComputer = TRUE;
}
}
} // 设置【HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces】
// 改动MTU=1500
// 假设不存在,则返回
HKEY hMainKey = NULL;
LONG lRetCode = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces"),0,KEY_READ,&hMainKey);
if(lRetCode != ERROR_SUCCESS)
{
return TRUE;
}
// 遍历全部网口,改动MTU
DWORD dwIndex = 0;
TCHAR swzSubKey[MAX_PATH] = _T("");
DWORD dwNameLen = MAX_PATH;
while(ERROR_SUCCESS == ::RegEnumKeyEx(hMainKey, dwIndex, swzSubKey, &dwNameLen, NULL, NULL, NULL, NULL))
{
// 构造子键全路径
CString strFullSubKey = _T("SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces\\");
strFullSubKey += swzSubKey;
// 改动MTU
if (CUtil::IsKeyExist(HKEY_LOCAL_MACHINE, strFullSubKey, _T("MTU")))
{
INT iValue = 0;
// 获取键值
if (CUtil::ReadKey(HKEY_LOCAL_MACHINE, strFullSubKey, _T("MTU"), iValue))
{
// 假设键值不是MTU默认值,则改动
if (iValue != MTU_DEFAULT)
{
// 假设写入失败,则依照发送
if (!CUtil::WriteKey(HKEY_LOCAL_MACHINE, strFullSubKey, _T("MTU"), MTU_DEFAULT))
{
lenPacket = NOT_SET_FAST_SEND_DATAGRAME_UDP_LENGTH;
return FALSE;
}
bIsToRestartComputer = TRUE;
}
}
}
// 重置缓存
memset(swzSubKey, 0, sizeof(swzSubKey));
dwNameLen = MAX_PATH;
// 下一个子项
dwIndex ++;
}
::RegCloseKey(hMainKey); return TRUE;
}

可是须要注意的是,改动此值须要确保小于或者等于整个网络路径的MTU,如何检查整个网络的MTU呢?能够通过运行以下指令获取:

ping -f -n 1 -l 1472 192.168.0.2

当中,1472为发送的包长度,假设运行结果为0,表示可以发送;可以继续提高1472,否则减少;直至获取最大值。

详细代码例如以下所看到的:

// 获取网络MTU
// ulDestIP【in】:目标IP
// 返回:MTU
UINT GetLanMTU(ULONG ulDestIP)
{
// 初始化
UINT lenPacket = NOT_SET_FAST_SEND_DATAGRAME_UDP_LENGTH;
// 指令缓存
CHAR szCmdBuf[MIDDLE_BUF_LENGTH];
memset(szCmdBuf, 0, sizeof(szCmdBuf));
// 构造指令
sprintf_s(szCmdBuf, MIDDLE_BUF_LENGTH, "ping -f -n 1 -l 1472 %s",
inet_ntoa(*(struct in_addr *)&ulDestIP));
// 运行指令
INT iRet = system(szCmdBuf);
// 假设MTU是
if (iRet == 0)
{ lenPacket = MAX_SUPER_DISPLAY_UDP_LENGTH;
}else
{
CUtil::OutputConsoleLogString("LAN's MTU isn't 1500");
} return lenPacket;
}

关于提高UDP发送效率的方法的更多相关文章

  1. iOS开发——实用篇&提高iOS开发效率的方法和工具

    提高iOS开发效率的方法和工具 介绍 这篇文章主要是介绍一下我在iOS开发中使用到的一些可以提升开发效率的方法和工具. IDE 首先要说的肯定是IDE了,说到IDE,Xcode不能跑,当然你也可能同时 ...

  2. 提高python执行效率的方法

    python上手很容易,但是在使用过程中,怎么才能使效率变高呢? 下面说一下提高python执行效率的方法,这里只是说一点,python在引入模块过程中提高效率的方法. 例如: 1.我们要使用os模块 ...

  3. <转>提高iOS开发效率的方法和工具

    介绍 这篇文章主要是介绍一下我在iOS开发中使用到的一些可以提升开发效率的方法和工具. IDE 首先要说的肯定是IDE了,说到IDE,Xcode不能跑,当然你也可能同时在使用AppCode等其他的ID ...

  4. 提高iOS开发效率的方法和工具

    http://www.cocoachina.com/ios/20150717/12626.html 介绍 这篇文章主要是介绍一下我在iOS开发中使用到的一些可以提升开发效率的方法和工具. IDE 首先 ...

  5. 50个提高PHP编程效率的方法

      用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的“函数”(译注:PHP手册 ...

  6. 提高PHP编程效率的方法

    用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的“函数”(译注:PHP手册中说 ...

  7. iOS-提高iOS开发效率的方法和工具

    提高iOS开发效率的方法和工具 介绍 这篇文章主要是介绍一下我在iOS开发中使用到的一些可以提升开发效率的方法和工具. IDE 首先要说的肯定是IDE了,说到IDE,Xcode不能跑,当然你也可能同时 ...

  8. 提高SQL查询效率的30种方法

    转载:提高SQL查询效率的30种方法 内容摘录如下: 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中 ...

  9. 提高SQL执行效率的16种方法

      项目中优化sql语句执行效率的方法:1)尽量选择较小的列2)将where中用的比较频繁的字段建立索引3)select子句中避免使用'*'4)避免在索引列上使用计算.not in 和<> ...

随机推荐

  1. Cmake 实现debug和release lib依赖项处理

    一.说明 最近用cmake开发东西,编译vs时候,发现debug和release版本的lib库的依赖项问题,故此小结一下.若有不对之处,还请看官多多指教. 使用的工程有自己编写的工程,也有借用第三方库 ...

  2. 一起学JAVA之《spring boot》03 - 开始spring boot基本配置及项目结构(转)

    <div class="markdown_views"> <h3 id="一导航"><a name="t0"& ...

  3. 账号被盗!请勿在CSDN,回复不论什么消息。

    账号被盗!请勿在CSDN,回复不论什么消息.

  4. js实现第一次打开网页弹出指定窗口(常用功能封装很好用)

    js实现第一次打开网页弹出指定窗口(常用功能封装很好用) 一.总结 1.常用功能封装:之前封装的cookie的操作函数非常好用,我自己也可以这么搞 二.js实现第一次打开网页弹出指定窗口 练习1:第一 ...

  5. 数据库中substring的用法 CONVERT(varchar(12) , getdate(), 112 )

    Sqlserver中常常要操作一些时间类型的字段转换,我又不太记得住,所以搜集了下面的一些SqlserverConvertDateTime相关的资料发表在自己的小站里,方便自己以后要用的时候寻找,望对 ...

  6. 解密Arm中国:全球最具影响力的芯片公司中国布局浮出水面

    经济观察报 记者 陈伊凡 沈怡然 李华清 对于Arm与中国合资公司事宜,5月4日下午,Arm授权的代表邮件回复<经济观察报>称:“合资公司目前刚开始运营”,“我们的重点是让这个新的合资公司 ...

  7. stm32的DMA传输一半中断

    这里本想做一个录音程序 硬件很简单: MIC(麦克风)放大滤波电路---->stm32的ADC----->DMA通道----->一个数组缓存------->通过FATFS的  ...

  8. ETL概述 分类: H2_ORACLE 2013-08-23 10:36 344人阅读 评论(0) 收藏

    转自:http://blog.csdn.net/leosoft/article/details/4279536 ETL,Extraction-Transformation-Loading的缩写,中文名 ...

  9. Python 语法细节(Python 2.x 与 Python 3.x 语法差异)

    Language differences and workarounds 查询 Python 语言版本: >> import sys >> sys.version '3.5.2 ...

  10. Android多线程研究(1)——线程基础及源码剖析

    从今天起我们来看一下Android中的多线程的知识,Android入门容易,但是要完成一个完善的产品却不容易,让我们从线程开始一步步深入Android内部. 一.线程基础回顾 package com. ...