(原)关于udp的socket发送数据耗时的问题探讨
转载请注明出处: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发送数据耗时的问题探讨的更多相关文章
- 对于socket发送数据时是否要加锁及write read的阻塞非阻塞
偶尔讨论到了socket发送数据时是否应该加锁的问题,就在网上查了一下,下面是大神陈硕的答案 对于 UDP,多线程读写同一个 socket 不用加锁,不过更好的做法是每个线程有自己的 socket,避 ...
- .net 中异步SOCKET发送数据时碰到的内存问题
做CS的开发一直都是这样的方式: server端用 C++编写,采用IOCP机制处理大量客户端连接.数据接收发送的问题 client端用 C++ 或C# 写,没什么特殊要求. 最近工作时间上比较宽裕, ...
- c++ socket发送数据时,sendData = char * string 导致的乱码问题
解决方法:将string 通过copy函数复制到某个char[] 1. string res =“xxx”; char arr[100]; int len = res.copy(arr, 100); ...
- udp网络程序-发送、接收数据
1. udp网络程序-发送数据 创建一个基于udp的网络程序流程很简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 代码如下: #coding=utf-8from socket im ...
- C#中UDP(Socket)
1 使用无连接的套接字,我们能够在自我包含的数据包里发送消息,采用独立的读函数读取消息,读取的消息是使用独立的发送函数发送的.但是UDP数据包不能保证可靠传输,存在许多的因素,比如网络繁忙等等,都有可 ...
- 安卓使用Socket发送中文,C语言服务端接收乱码问题解决方式
今天用安卓通过Socket发送数据到电脑上使用C语言写的服务端,发送英文没有问题,可当把数据改变成中文时,服务端接收到的数据确是乱码. 突然想到.VS的预处理使用的是ANSI编码.而安卓网络数据都是U ...
- C# Socket发送接收字节数组和十六16进制之间转换函数
近期在使用远程网络模块的时候, 需要用的Socket发送数据,远程模块指令为16进制. 官方提供的DEMO比较繁琐.不方便新手使用. 下面的转换函数可大大方便新手使用. // 16进制字符串转字节数组 ...
- Java中udp/tcp的发送和接收
InetAddress UDP例程: 发送数据: 接收数据: 结果: TCP例程: 发送数据: 接收数据: 结果:
- 通过 UDP 发送数据的简单范例
package j2se.core.net.udp; import java.io.IOException;import java.net.DatagramPacket;import java.net ...
随机推荐
- Django复习1
django常用命令:http://www.cnblogs.com/ldq1996/p/7731930.html Django查询SQL语句: http://www.cnblogs.com/ldq19 ...
- 上海交大ACM总教头俞勇讲述“最聪明人的故事”
这是一场世界大学生之间"最强大脑"的较量:这是拥有数十年历史的ACM国际大学生计算机程序设计大赛的赛场:斯坦福.加州理工.麻省理工.哈佛--当一个又一个在计算机科学领域拥有世界顶尖 ...
- 关于 win10启动错误 Error:16
那个软件报这个错误,就打开属性 -- 兼容性 -- 打勾以管理员身份运行
- Yii2 baisic版gii的使用和分页
一.Gii 的使用 1.配置 gii 的位置: 在 config/web.php 里面: if (YII_ENV_DEV) { $config['bootstrap'][] = 'gii'; $con ...
- NodeJS缓冲区
NodeJS缓冲区 JavaScript语言本身在I/O时只有字符串数据类型,没有二进制数据类型,但在处理流数据时,必须用到二进制数据,因此在Node中,定义了一个Buffer类作为存放二进制数据的缓 ...
- Mac使用Xcode配置openGL
Mac使用Xcode配置openGL 博主这学期有图形学课要用到OpenGL,于是首先就开始配置开发环境了.应该说网上Windows上配置OpenGL教程比较多,Mac版的比较少.博主特来分享配置过程 ...
- PAT基础6-11
6-11 求自定类型元素序列的中位数 (25 分) 本题要求实现一个函数,求N个集合元素A[]的中位数,即序列中第⌊N/2+1⌋大的元素.其中集合元素的类型为自定义的ElementType. 函数接口 ...
- openstack之Neutron网络模式vlan,gre,vxlan详解
第一:neutron openvswitch + vlan虚拟网络 一:基础知识 vlan基础知识 1.vlan介绍 1.1:首先说下lan,LAN 表示 Local Area Network,本地局 ...
- iOS WKWebview 网页开发适配指南【转】
微信iOS客户端将于2017年3月1日前逐步升级为WKWebview内核,需要网页开发者提前做好网站的兼容检查和适配.如有问题,可参考文末联系方式,向我们咨询. 背景 WKWebView 是苹果在iO ...
- 使用linux kernel代码编译perf工具
环境:Qemu + ARMv8 perf是一款综合性分析工具,大到系统全局性性能,再小到进程线程级别,甚至到函数及汇编级别. 在内核源码目录下执行编译脚本: #!/bin/bash cross_com ...