转载请注明出处: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. [NOIp2018提高组]旅行

    [NOIp2018提高组]旅行: 题目大意: 一个\(n(n\le5000)\)个点,\(m(m\le n)\)条边的连通图.可以从任意一个点出发,前往任意一个相邻的未访问的结点,或沿着第一次来这个点 ...

  2. JSX设置CSS样式详解

    JSX设置CSS样式详解 1. 使用className设置样式(CSS的其他选择器也是同理) (1)定义一个CSS文件style.css,和普通CSS一样定义class选择器 .sty1{//和普通C ...

  3. BZOJ3324 : [Scoi2013]火柴棍数字

    为了使数字最大,首先要最大化其位数. 设$f[i][j][k]$表示从低到高考虑了$i$位,手头火柴棍个数为$j$,第$i$位是不是$0$时,最少移动多少根火柴. 若$f[i][0][非0]\leq ...

  4. 【枚举】Consonant Fencity @upcexam5110

    时间限制: 3 Sec 内存限制: 512 MB 题目描述 There are two kinds of sounds in spoken languages: vowels and consonan ...

  5. ACM-ICPC 2018 南京赛区网络预赛 E题

    ACM-ICPC 2018 南京赛区网络预赛 E题 题目链接: https://nanti.jisuanke.com/t/30994 Dlsj is competing in a contest wi ...

  6. JS如何判断浏览器类型和详细区分IE各版本浏览器

    /* * 描述:判断浏览器信息 * 编写:LittleQiang_w * 日期:2016.1.5 * 版本:V1.1 */ //判断当前浏览类型 function BrowserType() { va ...

  7. 加速Android Studio编译速度

    一.修改运行内存 进入项目,菜单栏-help-Edit Custom VM Option   Paste_Image.png 添加或修改为: -Xms2048m -Xmx2048m -XX:MaxPe ...

  8. Android的Databinding-单向绑定

    两种方式实现观察绑定. 一.POJO类实现android.databinding.Observable,在属性set方法中调用notifyPropertyChanged(BR.lastName); 其 ...

  9. EF Core中执行Sql语句查询操作之FromSql,ExecuteSqlCommand,SqlQuery

    一.目前EF Core的版本为V2.1 相比较EF Core v1.0 目前已经增加了不少功能. EF Core除了常用的增删改模型操作,Sql语句在不少项目中是不能避免的. 在EF Core中上下文 ...

  10. Docker Mongo数据库开启用户认证

    一.启动mongo容器的几种方式 #简化版 docker run --name mongo1 -p 21117:27017 -d mongo --noprealloc --smallfiles #自定 ...