转载请注明出处: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. Spring配置JDBCTemplate

    案例:单测查询全部学生 项目结构: 1.导入部署jar包:spring-jdbc <!--spring-jdbc--> <dependency> <groupId> ...

  2. 面试题fugui

    1.什么是栈溢出,在什么情况下可能会出现 栈溢出是由于C语言系列没有内置检查机制来确保复制到缓冲区的数据不得大于缓冲区的大小,因此当数据足够大时,将会溢出缓冲区的范围. python函数调用是通过栈这 ...

  3. 03爬虫 爬取hfutxc成绩

    #-*- coding:utf-8 -*- # -*- coding: utf-8 -*- #encoding:utf-8 import urllib import urllib2 import co ...

  4. Coins [POJ1742] [DP]

      Description 给出硬币面额及每种硬币的个数,求从1到m能凑出面额的个数. Input 多组数据,每组数据前两个数字为n,m.n表示硬币种类数,m为最大面额,之后前n个数为每种硬币的面额, ...

  5. input中autocomplete属性

    autocomplete="off":表示刷新页面时,input中的value值清空 <input type="text" id="q" ...

  6. new Random().Next(1, 100); 多线程同时执行结果很高概率相同,

    /// <summary> /// new Random().Next(1, 100); 多线程同时执行结果很高概率相同, /// 是用的当前时间为seed,时间相同结果相同 /// // ...

  7. too much recursion(太多递归)Uncaught RangeError: Maximum call stack size exceeded BootstrapValidator报错

    在BootstrapValidator中已默认遵守Bootstrap规则,form里的每个输入项目必需包含在类为form-group的标签里,否则BootstrapValidator中定义的field ...

  8. Excel 驼峰表达式

    =LEFT(A1,1)&MID(SUBSTITUTE(PROPER(A1),"_",""),2,100)

  9. js-工具函数

    /** * 将文件大小转换成 ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],单位 * @param bytes * @returns */ ...

  10. javascript日期时间操作库推荐

    https://github.com/datejs/Datejs 链接: https://pan.baidu.com/s/1QTGhxslarNyW_0kB6gyJYA 提取码: ibab 如果这篇文 ...