转载请注明出处:http://www.cnblogs.com/lihaiping/p/6811791.html

本学习笔记,仅用于问题探讨,如有不同,可以讨论。

最近在看流媒体分发服务器的相关代码,其中对于网络udp数据发送耗时的研究,这块有一点点疑问:

udp的sendto发送数据的耗时大概为多少?他的耗时跟发送的数据包大小有没有关系?跟对端的ip地址是否存在,有没有关系?是否存在ip地址在的网络,sendto耗时小,对于ip地址网络不通的耗时是不是比较大?

网络搜索,csdn论坛有人问了:http://bbs.csdn.net/topics/60039818

然后我拷贝了论坛的测试程序,在vs上运行测试了一把,同时进行了部分修改。

//测试网络发送耗时问题
int udp_socket_send_test(int argc, char* argv[])
{
DWORD LastTime;
DWORD Curtime;
DWORD EscpTime;
WSADATA wsaData;
long addr;
long wrc;
long lngSendTimeOut = ;
long lngRecvTimeOut = ;
SOCKADDR_IN sockObject;
SOCKET sSend;
u_long nonblocking = ;
char transbuf[] ;//这个地方的数据大小,只是跟填充网络发送缓冲区有关
char IPADDR[];
memset(transbuf,'a',sizeof(transbuf)); WSAStartup(0x202,&wsaData);
sSend = socket(AF_INET, SOCK_DGRAM,);
//设置为非阻塞模式
ioctlsocket(sSend,FIONBIO,&nonblocking);//在非阻塞模式下,udp发送基本不占用时间,而且跟ip地址无关系
setsockopt(sSend,SOL_SOCKET,SO_SNDTIMEO, (char*)&lngSendTimeOut,sizeof(lngSendTimeOut) );
setsockopt(sSend,SOL_SOCKET,SO_RCVTIMEO,(char*)&lngRecvTimeOut,sizeof(lngRecvTimeOut) );
sockObject.sin_port = htons();
sockObject.sin_family = AF_INET;
for(int i = ;i < ; i++)
{
sprintf(IPADDR,"192.168.0.1%d",i);
LastTime = GetTickCount();
addr = inet_addr((char *)IPADDR);
memcpy(&sockObject.sin_addr,&addr,sizeof(addr));
//这个地方的耗时跟两个因素有关系
//官方:
//If no buffer space is available within the transport system to hold the data to be transmitted,
//sendto will block unless the socket has been placed in a nonblocking mode.
//也就是说,对于sendto函数,他的发送返回成功并不代表网络发送了,他只是将数据发送到传输层的缓冲区,就返回结果
//而对于阻塞的socket,当这个ip地址即使不存在,但缓冲区未满的情况下,他也是返回成功的,而且基本不耗时,
//但当缓冲区满了以后,sendto就会阻塞,这个时候会产生耗时
//对于非阻塞的socket,缓冲区未满的时候,它基本不占发送时间,满了,sendto也会立即返回结果,整个过程基本不耗时 wrc = sendto(sSend,transbuf,sizeof(transbuf),,(struct sockaddr *)&sockObject,sizeof(sockObject));
Curtime = GetTickCount();
EscpTime = Curtime - LastTime;
if (wrc != SOCKET_ERROR)
{
printf("Send Some Data To %s,Use Time:%d ms\n",IPADDR,EscpTime);
// Sleep(1000);
}
else
{
printf("*Send Some Data To %s,failed ,Use Time:%d ms,sendto return value:0x%x\n",IPADDR,EscpTime,wrc);
}
Sleep(); }
closesocket(sSend);
WSACleanup();
return ;
}

上面是我测试的时候的一个源码。

然后我在srs论坛里面也跟群友咨询了这个问题,他的拷贝了一个官方的解释给我:

If no buffer space is available within the transport system to hold the data to be transmitted, sendto will block unless the socket has been placed in a nonblocking mode.

直接翻译过来的意思为:

如果没有可用的缓冲区空间运输系统内的数据传输、sendto将阻止,除非socket被放置在一个非阻塞模式。

然后我在源码里面也进行注释:

udp 的sendto函数,其实他只是将发生的数据包进行了一次拷贝,拷贝到了传输层的网络缓冲区,然后函数返回结果。所以sendto函数的返回值并不能代表网络真实的一个发送情况结果。既然理解了上面的这个,所以udp的sendto耗时基本可以忽略了。因为数据拷贝基本不占用多大实际时间。但对于阻塞的socket,当网络缓冲区满了以后,sendto就会阻塞。而对于非阻塞的socket,即使网络缓冲区满了,他也会立即返回,不会进行阻塞等待,所以这种情况下适合于流媒体发送数据,即使单线程作战分发也是可以的。

(原)关于udp的socket发送数据耗时的问题探讨的更多相关文章

  1. 对于socket发送数据时是否要加锁及write read的阻塞非阻塞

    偶尔讨论到了socket发送数据时是否应该加锁的问题,就在网上查了一下,下面是大神陈硕的答案 对于 UDP,多线程读写同一个 socket 不用加锁,不过更好的做法是每个线程有自己的 socket,避 ...

  2. .net 中异步SOCKET发送数据时碰到的内存问题

    做CS的开发一直都是这样的方式: server端用 C++编写,采用IOCP机制处理大量客户端连接.数据接收发送的问题 client端用 C++ 或C# 写,没什么特殊要求. 最近工作时间上比较宽裕, ...

  3. c++ socket发送数据时,sendData = char * string 导致的乱码问题

    解决方法:将string 通过copy函数复制到某个char[] 1. string res =“xxx”; char arr[100]; int len = res.copy(arr, 100); ...

  4. udp网络程序-发送、接收数据

    1. udp网络程序-发送数据 创建一个基于udp的网络程序流程很简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 代码如下: #coding=utf-8from socket im ...

  5. C#中UDP(Socket)

    1 使用无连接的套接字,我们能够在自我包含的数据包里发送消息,采用独立的读函数读取消息,读取的消息是使用独立的发送函数发送的.但是UDP数据包不能保证可靠传输,存在许多的因素,比如网络繁忙等等,都有可 ...

  6. 安卓使用Socket发送中文,C语言服务端接收乱码问题解决方式

    今天用安卓通过Socket发送数据到电脑上使用C语言写的服务端,发送英文没有问题,可当把数据改变成中文时,服务端接收到的数据确是乱码. 突然想到.VS的预处理使用的是ANSI编码.而安卓网络数据都是U ...

  7. C# Socket发送接收字节数组和十六16进制之间转换函数

    近期在使用远程网络模块的时候, 需要用的Socket发送数据,远程模块指令为16进制. 官方提供的DEMO比较繁琐.不方便新手使用. 下面的转换函数可大大方便新手使用. // 16进制字符串转字节数组 ...

  8. Java中udp/tcp的发送和接收

    InetAddress UDP例程: 发送数据: 接收数据: 结果: TCP例程: 发送数据: 接收数据: 结果:

  9. 通过 UDP 发送数据的简单范例

    package j2se.core.net.udp; import java.io.IOException;import java.net.DatagramPacket;import java.net ...

随机推荐

  1. Linux启动或禁止SSH用户及IP的登录,只允许密钥验证登录模式

    启动或禁止SSH用户登录 一般情况下,在使用Linux操作系统都不会去机房来操作机器,都是使用一些第三方的工具来操作. 比如使用SSH Secure File Transfer Client工具来传输 ...

  2. WC、KOI2017小随想..

    自从WC之后就一直想说些什么.. 嗯比较零碎.. Part A WC,我通过我的双眼看到了我想要的 嗯,就是在上面道出自己的想法.自己的思想 也是自己在十二月的迷茫后看到的曙光吧.. 感动.激动.难以 ...

  3. yii2 用 bootstrap 给元素添加背景色

    使用 bootstrap 给元素添加背景色 1.bootstrap 官网:http://getbootstrap.com/ 2.bootstrap 中文官网:http://v3.bootcss.com ...

  4. 前端利器Emmet

    前端利器Emmet Emmet可以通过缩写生成代码片段,可以提升前端开发的效率.使用方法就是输入HTML或者CSS的缩写,然后按tab键自动生成.原文在这里 后代 > <!-- nav&g ...

  5. itchat分析微信好友的个性签名

    itchat分析微信好友的个性签名 itchat是一个开源的微信个人号python接口(公众号.企业号接口为itchatmp).使用它可以非常优雅地操纵个人微信号.文档链接 七夕到了,博主也要自娱自乐 ...

  6. vim设置一个tab为4个空格,设置行号

    这我就再当前用户下,不是root权限.本身是没有.vimrc这个文件的 vim  ~/.vimrc 新建了这个文件 然后在其中输入 保存. 这样设置完就一个tab是4个空格,并且就有行号了.重新打开v ...

  7. pygame-KidsCanCode系列jumpy-part10-角色动画(上)

    上一节学习如何利用spritesheet加载图片,但是player仍然是一张静态的图片,比较枯燥,我们要让它动起来! Player类,先把各种状态的图片加载起来: # 加载各种状态的图片序列 def ...

  8. python之使用set对列表去重,并保持列表原来顺序(转)

    https://www.cnblogs.com/laowangball/p/8424432.html #原始方法,但是会打乱顺序 mylist = [1,2,2,2,2,3,3,3,4,4,4,4]m ...

  9. SpringBoot(十):读取application.yml下配置参数信息,java -jar启动时项目修改参数

    读取application.yml下配置参数信息 在application.yml文件内容 my: remote-address: 192.168.1.1 yarn: weburl: http://1 ...

  10. 【JVM】垃圾收集器

    程序计数器.Java虚拟机栈.本地方法栈分配的内存是确定的,生命周期与线程同样.所以不须要过多考虑回收问题. 而Java堆和方法区仅仅有运行时才知道有哪些对象被创建,须要多少内存,这部分的内存分配和回 ...