首先给大家推荐下Markdown,我想用过github的同僚一定很熟悉了,这篇文章的排版就是使用的markdown,以后我们不必再去适应各个博客系统自己繁杂的排版方式了。
网络编程是什么?
给大家从招聘信息上截取几段内容:
熟悉Socket编程,熟悉Tcp/Ip协议栈;
熟悉TCP/IP协议、UDP协议,有相关的协议开发经验;
熟悉网络编程/多线程编程技术;
大家应该很清晰了吧,关键词就是TCP/IP,Socket,我再附加一个多线程。下面开始我的网络编程之旅。
tcp/ip协议分析
其实协议分析并不是大众认为的网络编程的范畴,现在网络编程已经完全和socket等同了。socket是表面,TCP/IP协议是里,有了协议分析的经历更会让你的网络编程之路更加平坦。
想必有些童鞋经历过这样的公司吧,对公司内部的上网行为进行监控:你访问过哪些域名,上传下载过哪些资源,你占用了多少带宽流量,甚至你的邮件正文,附件都会呈现在监控系统上。这就是协议分析的杰作。经典的网络四层模型构成了协议分析的基础。
了解TCP/IP协议一本书足矣《TCP/IP详解 卷1:协议》,进行协议分析并也不需要我们自己从头做起,我们完全可以站在巨人的肩膀上,这个巨人就是pcap,另外还有非常知名的基于pcap实现的开源项目供我们参考,比如snort、tcpdump、wireshark特别是snort的功能模块化设计和实现非常经典,应用在大型协议分析项目中极为合适。至于作为协议分析工具的tcpdump和wireshark,不会使用的话咱就别好意思说咱是干这行的了。
socket编程
socket的扫盲书籍及文章太多太多,咱在这就不废话了。起初我有个疑问,对很多公司招聘信息上写的熟悉Socket编程感到很不解,因为我觉得是很简单的事情,无非就是调用几个API,理解下三次握手、listen...等等几个状态。之后在真正做企业级的牵扯到多Client对单Server网络编程和具体的网络环境时才慢慢理解了那些招聘信息的含义和需求深度。(以下如不特殊指定均指TCP协议)
-
局域网
我们这个项目主要针对局域网用户,相比广域网的网络环境,几乎可以忽略带宽考虑,用户并发数也相对较小,对性能和效率要求较低,另外业务较复杂。在这种情况下最合适的就是采用RFC(远程过程调用),于是我们首先想到了开源的RFC框架,经他人尝试推荐采用了RCF,相当于我们只需要在此框架上套上业务逻辑即可,起初在我们实践和小规模的测试中并未发现有问题,但是真正模拟到高并发情况时却在网络层出现了不可控的错误,初步判断是RCF的线程模型和我们的使用场景不一致,于是决定开发一套自己的网络库,于是在一位以前有过网游经验的研发人员的指导下,我们一起开发了一个基于boost asio的远程过程调用框架,boost asio的网络模型在windows下采用的完成端口,在类unix系统下采用的是相应的多路复用接口,由于在局域网环境下,用户并发数也不多,也就是用好boost asio,设计好网络传输协议,处理好数据封包解包就好了,并未遇到太大的问题。 -
广域网
首先抛开广域网复杂的网络环境不谈,这个产品是个互联网项目,面向普通用户,有些类似于IM软件,由于有QQ这个优秀的采用UDP协议的例子,我们也曾经在TCP和UDP协议间犹豫过,但是鉴于UDP实现的难度太大,还是采用了TCP来实现C/S通信。客户端(windows,linux,android),服务端(linux)网络库的设计编写都由我负责,考虑到以后可能出现的海量并发,在服务端我采用了master——worker模型,一个事件循环一个线程的多线程网络模型,这样可以充分利用服务器的多核资源,客户端和服务端的网络库都采用了libevent。服务端的设计思路及代码实现可以参考我的github:highPerformanceNetworkServer(这只是个演示demo,离企业及应用还有许多需要自己完善的)。
前面说到了socket编程的简单VS深度,其实你需要了解、注意、掌握的东西有很多,比如MTU,MSS,SO_LINGER,TCPNODELAY,TIMEWAIT,keepalive(最好用应用层心跳包),串话...,在实际的编写和使用中你会慢慢知道的。
另外很重要的一点就是网络传输协议的设计,这也进行socket编程的重中之重,可以参考我曾经的文章网络传输数据格式的选择。
扩展话题
-
UDP
UDP也属于socket编程的范畴,把他单拿出来是因为他的使用范围相比较TCP还是有局限性的。在做可靠信息传输这种应用中,腾讯QQ的技术让我们体会到了他的可靠和高效。业界也有相应的对UDP可靠传输的包装,我仔细研究过的是UDT。在我们的产品应用中,主要是使用UDP来进行NAT穿透,我和同事一起使用过UDP和UDT进行NAT穿透,很有效,但依然有局限性:比如针对对称nat。另外使用UDP来进行相对可靠的视频传输,现在我的一个同事在专心搞这块,我想以后从他那一定可以学到不少更深的技术。 -
多线程
如果搞网络编程不掌握多线程就好像你只有一条腿一般。比如我前面说所的master——worker模型,一个事件循环一个线程,一些涉及到IO bound、CPU bound、心跳包、客户端抢带宽都可以利用线程来进行相应的解决。 -
Python
用python来写网络测试脚本,事半功倍。
推荐书籍
-
《TCP/IP详解 卷1:协议》
-
《UNIX网络编程》
这两本书不用多说,大家肯定都铁铁的知道经典程度。 -
《Linux多线程服务端编程》
这本陈硕老师的书籍实战性很强,讲述的思维和问题都是和实战紧密相联的。我感觉代码部分比较复杂,用了不少我不熟悉的c++特性,还需进一步学习理解