谈谈网络编程(基于C++)

转载 2015年01月27日 10:28:24

这篇文章讲了一点网络编程的一些新路,一点体悟。学习就是这种不断总结提高的过程。

设计到进程,线程,线程池,reactior和proactor并发编程模式,IOCP,linux下的epoll。。。。。




我从事的是企业级的软件开发,纵观当今的企业级软件,单机模型已经越来越少,更多的是C/S模型,目前 client 和 server 之间通信是通过 socket 技术来实现的。

  上面提到了 socket 技术,自然要学习 TCP/IP 协议,对于 TCP/IP 的理论,学习 Richard 的《TCP/IP 详解卷1:协议》我认为是不二的选择,这本书涵盖内容很多,如果对于只是实现C/S通信的网络库而言,仅需要了解其中介绍 UDP 和 TCP 的章节就好,扎实的理论基础会为你以后遇到网络传输中出现的问题给予很好的解释,也便于你解决这些问题。理论联系实现,还是 Richard 的《UNIX 网络编程卷1:套接口 API》(俗称 UNP1),这本书我一直在看,但是还没看完,我认为这是网络编程的圣经,你掌握了这本书,基本也就掌握了网络编程,甚至细枝末节也能覆盖到。

谈谈网络编程(基于 C++ 语言)

  以下只涉及 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 的实现。

  今天,对于网络编程先总体并且概括的介绍下吧,其实还有很多问题没有涉及,我本人对网络编程十分的感兴趣,现在也在从事这方面的工作,所以以后有机会希望和大家一起分享一些更细致全面的知识,鉴于本人水平有限,希望大家能对文章中出现的错误给予批评指正,我们一起进步……


相关文章推荐

C/C++ socket网络编程扫盲篇

引言 socket 是“套接字”的意思,是计算机之间进行通信的一种约定,也可以认为是一种技术。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。 sock...

C++基于TCP/IP简单的客户端、服务器通信程序实例

本篇文章实现了一个基于TCP 的

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

linux下C/C++网络编程基本:socket实现tcp和udp的例子

简单的linux下socket编程,分别基于TCP和UDP协议实现的简单程序 linux下socket编程可以概括为以下几个函数的运用: socket() bind() listen()...

C/C++网络编程总结与ZeroMQ

现在几乎所有C/C++的后台程序都需要进行网络通讯,其实现方法无非有两种:使用系统底层socket或者使用已有的封装好的网络库。本文对两种方式进行总结,并介绍一个轻量级的网络通讯库ZeroMQ。 ...

C++网络编程

C++网络编程

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

C++网络编程方面的开源项目

Webbench是一个在linux下使用的非常简单的网站压测工具。它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力。...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:谈谈网络编程(基于C++)
举报原因:
原因补充:

(最多只允许输入30个字)