谈谈网络编程(基于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端的音视频通信。
相关问答
Windows 下进程间通讯的几个比较?1进程与进程通信进程是装入内存并准备执行的程序,每个进程都有私有的虚拟地址空间,由代码、数据以及它可利用的系统资源(如文件、管道等)组成。多进程/多线...
win10上不了网,疑难解答显示“ windows 无法与XXXXX 通信 (好像是dns服务器)”,无法?右键点击系统桌面左下角的“开始”,在打开的右键菜单中点击“运行”,也可以按下键盘上的Win+R键,打开“运行”对话框,点击确定。进入界面后,首先,清空DNS...
如何配置局域网中的 通信 协议[回答]不同的网络协议都有其存在的必要,每一种协议都有它所主要依赖的操作系统和工作环境。在一个网络上运行得很好的通信协议,在另一个看起来很相似的网...
电脑上显示 Windows 无法与设备或资源 通信 是什么意思,电脑也没有网?这是解决你电脑Windows无法与设备或资源通信的方法:第一步:控制面板--->网络和Internet--->网络和共享中心--->本地连接--->属性--->Inte...
windows 无法与设备或资源(主DNS服务器) 通信 怎么解决?怀疑是dns服务器的问题。解决方法:1、首先,打开网络和Internet设置。2、在弹出的窗口中点击“更改适配器选项”。3、右键点击“本地连接”,点击“属性...
arm开发板上的linux如何通过网口和 windows 的网口 通信 ,linux中的socket和 windows 下的socket能通用吗?在arm上实现ftp,然后windows上设一个ftp服务器(有这样的软件下,很多),arm上找到windows上设的服务器,就能传文件了。在arm上实现ftp,然后windows上设一个ftp.....
windows 11无法与dns服务器 通信 ?Windows11无法与DNS服务器进行通讯的话,建议右键点击网卡,在弹出餐单中选择属性,然后在tcpip选项当中,双击进入输入IP地址以及手动配置DNS。Windows11无法与D...
Windows 无法与设备或资源(主DNS) 通信 怎么办-ZOL问答1.首先,打开网络和Internet设置。2.在弹出的窗口中点击“更改适配器选项”。3.右键点击“本地连接”,点击“属性”。4.在弹出的对话框中打开“Internet协议版...
windows 无法与设备或资源 通信 怎么弄?应该是网络参数设置不正确。1、控制面板--->网络和Internet--->网络和共享中心--->本地连接--->属性--->Internet协议版本4(TCP/I...
计算机 网络 系统是由 通信 子网和什么构成的-ZOL问答一从数据通信和数据处理的功能上分析,一般从逻辑上将网络分为通信子网和资源子网两个部分。般而论,计算机网络有三个主要组成部分:若干个主机,它们为用户提供服...