谈谈网络编程(基于C++)
这里讲了一点网络编程的一些新路,一点体悟。学习就是这种不断总结提高的过程。
设计到进程,线程,线程池,reactior和proactor并发编程模式,IOCP,linux下的epoll。。。。。
讲到这里就要提一下 socket 技术了,要想理解socket自然要学习 TCP/IP 协议,对于 TCP/IP 的理论,学习 Richard 的《TCP/IP 详解卷1:协议》我认为是不二的选择,这本书涵盖内容很多,如果对于只是实现C/S通信的网络库而言,仅需要了解其中介绍 UDP 和 TCP 的章节就好,扎实的理论基础会为你以后遇到网络传输中出现的问题给予很好的解释,也便于你解决这些问题。理论联系实现,还是 Richard 的《UNIX 网络编程卷1:套接口 API》(俗称 UNP1),这本书我一直在看,但是还没看完,我认为这是网络编程的圣经,你掌握了这本书,基本也就掌握了网络编程,甚至细枝末节也能覆盖到。这边也推荐几个视频给大家看看。。。。
TCP/IP协议栈深度解析丨实现单机百万连接丨优化三次握手四次挥手
程序员必知必会的网络协议栈
以下只涉及 TCP 协议
紧接着学习转为实践,想想网络通信的场景:一个 server 要对应成百上千..个客户,这样必须要考虑到 server 的处理能力。
最简单的模型就是你用一个进程来处理所有的客户端连接,my god!你想想,在处理过程中如果有上百个连接同时请求服务,我们采用这种模式,首先下一个连接要等着上一个连接处理完(同步),这个在处理的连接还很有可能阻塞在数据操作(I/O)上,这样处理连接的效率之差及客户端的响应之慢我想几乎没有人能忍受吧。
好,为了提高效率,我们改进一下,对每一个客户连接产生一个线程(windows)或进程(linux)来处理,抛开线程或进程的上下文切换损耗不谈,也不谈 SMP,就单单看产生成千上百个线程和进程的可行性,对不起,咱操作系统可是有线程或进程资源上限的。
为了解决线程频繁切换造成的资源损耗和资源数限制问题,我们再改进一下,采用一个线程池来处理部分连接,其他连接排队等候,毕竟咱 cpu 不多,同时也就能处理那么几个连接,响应效率和处理效率依然提不上去。
想一个问题,其实我们的网络耗时一般都是在数据操作上(I/O),为了增加客户端的响应,我们可以把一次网络接入分为处理连接的线程和进行逻辑处理的线程,这样就可以极大地提高客户端的响应,但是记住一定要在逻辑处理线程中维护住这个连接的会话。这样仿佛还不错,no,no,其实也不好,你并不知道什么时候有数据到来需要处理,你必须要轮询来确定可不可以进行数据操作….,效率还是不好啊。
好了,咱不自己独创技术了,选用经典的 Reactor 和 Proactor 并发编程模式,他们都是基于事件驱动的,咱呢就是把网络中需要处理的事件注册到事件管理器中去(比如网络行为事件,IO 操作事件…..),然后等事件状态就绪了,他就用回调的方式通知咱去处理,怎么样,这样至少 CPU 不会闲着了,只用一个线程就可以处理几乎所有的事件了。但是 Reactor 和 Proactor 还是有很大区别的,Reactor 对于I/O这一步是需要自己处理的,但是 Proactor 对于I/O这一步是由操作系统完成的,然后把完成事件通知你,然后你就可以进行下一步操作了(比如从缓冲区 buf 里读数据),比自己操作I/O这种方式快多了吧。目前,我在 windows 下写网络库采用的是 Proactor 模式:用 windows 自己提供的完成端口模型(IOCP)实现,在 linux 下,由于 linux 没有很好的异步I/O机制,只好采用 Reactor 方式了:使用的是 linux 特有的 epoll。
谈一些我自己的看法:从我的理解上,对于大部分网络库而言,很多都是I/O密集型的,这样仿佛采用 Proactor 模式更有优势,但是 linux 下没有和 windows 下 IOCP 类似的机制,但是可以采用 epoll 加任务队列的方式实现一套,但是仿佛很复杂,我想自己实现就算了吧。好在“山穷水复疑无路,柳暗花明又一村”,boost asio 已经为我们封转好了 windows 和 linux 下的 Proactor 实现,windows 采用的是完成端口,linux 下采用的是 epoll 加任务队列的方式实现。下一步我准备把目前 linux 下采用 epoll 方式实现的 Reactor 网络库改为 boost asio 的实现。
今天,对于网络编程先总体并且概括的介绍下吧,其实还有很多问题没有涉及,我本人对网络编程十分的感兴趣,现在也在从事这方面的工作,所以以后有机会希望和大家一起分享一些更细致全面的知识,鉴于本人水平有限,希望大家能对文章中出现的错误给予批评指正,我们一起进步……
手把手教你搭建视频通信系统——windows版
前两天说了iOS介绍了Android,今天就和大家说一下windows端如何搭建视频通信系统。
一、准备:
1、首先在图鸭官网:http://tucodec.com 进行注册,获得SDK中所需要的APPKey、AppSecret,注册登录后如下图所示:
图1 注册后获取AppKey、AppSecret
点击SDK下载按钮跳转到下载界面,选择下载Windows中所需SDK和Demo。
图2 SDK下载展示
如图所示我们提供了vs2013版本和vs2015版本的SDK及相应的WinDemo。
图3 SDK解压后内容
2、下载visual studio开发工具并安装,因为vs2013和vs2015自带的一些库和编译选项有些许不同,所以必须选择与SDK匹配的VS工具进行开发。
3、安装完成后双击打开图3中的WinDemo.sln,便可以看到如图4的工程界面,把生成类型调整为Debug/x86,然后编译WinDemo项目。
图4 WinDemo项目截图
4、在vs中点击“本地调试器”即可运行本demo,main函数的两个参数已在工程配置选项中赋予,如图5所示
图5 项目里的main参数设置
或者手动将opencv和Tucodec_SDK_Windows的bin目录下的文件拷贝到exe所在的目录。然后在该文件夹下打开“命令提示符”或者“Windows PowerShell”,在命令行下面赋予WinDemo.exe两个参数,分别是自己的ID和对方的ID,然后运行即可。如图6所示
图6 在命令行中打开WinDemo.exe,效果和上面一样
5、SDK相关说明在《Windows端VoIP SDK使用说明》一文,已经做了详细介绍,本文接下来主要介绍WinDemo的代码结构,方便开发者理清开发流程。
二、WinDemo介绍
总的来说,Windows端的音视频通信系统主要包括音视频采集、音视频播放和VoIP负责的音视频传输三个模块。利用图鸭科技提供的SDK及由图鸭科技公司开源的转发服务器代码(http://www.tucodec.com),开发者可以搭建自己的音视频通信服务器。因此,开发者主要面对的问题就是Windows端的音视频采集与播放问题,也是本文着重介绍的地方。
1、视频采集和播放
有经验的开发者看到压缩包内的opencv目录便知道了在本Demo中对视频的处理借助了opencv的帮助,其优点是可以非常方便的进行视频采集和播放,为开发者屏蔽了与Windows硬件交互的诸多繁杂任务。Demo中的CVideoCap和CVideoRender两个类就是利用了opencv库进行视频的采集和渲染。
当然,opencv有一个比较大的缺点儿就是耗费系统资源比较多,如果电脑配置一般的话会发现开启opencv渲染视频后电脑的CPU负荷会出现大幅上涨。所以如果想把我们的SDK用于产品研发的话,推荐自己实现客户端的采集和播放功能,常用的有DirectShow,SDL,DirectX SDK等官方提供的SDK。
2、音频采集和播放
由于opencv不能完成音频相关的处理任务,所以Demo中使用了微软提供的Windows MultiMedia相关API完成音频采集和渲染功能,详见Demo中的CAudioCap和CAudioRender两个类。
音视频采集与播放的类关系如下图所示:
图7 音视频采集和播放的UML类图
3、CVoipManager类
这个类封装了音视频操作与VoIP之间的交互,是整个Demo的核心部分。其类图如下所示:
图8 CVoIPManager类图
部分方法和属性介绍:
m_clientNetwork:ClientNetwork实例,负责转发服务器的登录
m_voip:TYVoip实例,负责打通数据传输
m_voipCallback:TYVoip中的接口实现,是voip的视频回调接口,客户端从这个类中获得voip传过来的视频数据
m_selfID:本地的usrID
m_sessionID:会话ID
m_audioCap,m_audioRender,m_videoCap,m_videoRender:音视频采集渲染
m_ac,m_ai,m_vc,m_vi:音视频格式配置
m_nodeList:添加的通信节点列表
LoginServer:登录转发服务器(转发服务器需要提前配置好),因为是通过转发服务器做数据传输或P2P打洞,所以在添加对方为节点的时候要保证两者都是在线状态,当然这个在登录模块做了处理,如果对方还没上线会一直请求下去。
AddNote:添加一个通信节点
RemoveNote:移除一个通信节点
StartVoipTransmit:开始音视频采集和渲染以及传输
EndVoipTransmit:结束音视频采集和渲染以及传输
三、效果展示
1、自己登陆ID为1,添加节点为2,但2未上线的情况
可以看到本地视频回路已被打开,控制台打印信息主要有:
login success:表示登陆转发服务器成功
add node 2:表示添加节点2
get p2p addr of uid:2 fail:是在请求添加2节点,但是2节点还没有上线
2、本地ID为1,添加节点2,且节点2已上线
usr1本地窗口
usr2窗口
达到上图所示结果,就完成了Windows端的音视频通信。
相关问答
win10下如何设置防火墙允许 程序通信 ?虽然现在有很多防火墙软件,但一般用户来说,Windows自带的防火墙已经足够。可能一般我们在使用电脑的时候会忽视这个Windows自带的功能,有的人甚至还关闭它,但...
你好,请问 Windows 无法与设备或资源(主DNS服务器) 通信 怎么处...另外问一下,你的网络运营商是广电吗?广电这样的问题特别多。有用(0)回复xiaofan0830网上邻居——本地连接(当前使用的)——属性——选中协议——属性——...
windows 无法与设备或资源(主DNS服务器) 通信 怎么处理?-ZOL问答查看网络连接状态---->属性----->在安装目录下选择TCP/IP协议然后查看属性--->常规-->自动获取IP地址,自动获取DNS服务器地址。如果本来就是自动获取的话建...
WIN7系统: WINDOWS 无法与设备或资源(主DNS服务器) 通信 ?出现该种情况的原因失电脑的DNS服务器地址错误,可以通过进入到网络和共享中心,然后再点击网络属性,选择手动输入DNS服务器地址就可以解决了。具体的设置方法如...
用c语言或c++通过网线使电脑跟运动控制卡建立通讯怎么编程的?Synchronization(Windows)ProcessesandThreads(Windows)把这两个都看完(特别是文字部分),然后补补操作系统,你就学会了任意语言的多线程编程了...
windows 无法与设备或资源 通信 ?无法与设备或资源通信解决办法如下:打开【网络和共享中心】打开左侧的【更改适配器选项】,在【本地连接】处,右键点击【Internet协议版本4】;然后在DNS中,打...
windows 无法与设备资源dns 通信 ,局域网可用?在尝试访问网络时,如果遇到“无法与设备资源DNS通信”的错误提示,但局域网(LAN)仍然可以正常使用,可能有几个可能的原因。首先,这可能是因为DNS设备或...
windows 无法与设备或资源(主DNS服务器) 通信 怎么解决?怀疑是dns服务器的问题。解决方法:1、首先,打开网络和Internet设置。2、在弹出的窗口中点击“更改适配器选项”。3、右键点击“本地连接”,点击“属性...
windows 无法与设备或资源,主dns 通信 ?这是一个网络连接问题。原因是通常情况下,主DNS服务器会自动与你的计算机相连接,但是连接错误或无法连接会导致这一问题。可能是由于网络配置问题或DNS服...
windows 无法与主dns 通信 用管理员命令?操作方法01首先打开控制面板,在控制面板中,找到如下配置:网络和共享中心。点击进入02在网络和共享中心中,点击左上侧的更改适配器设置,进入配置适配器...