关于网络编程.docx

上传人:b****3 文档编号:2807281 上传时间:2022-11-15 格式:DOCX 页数:12 大小:33.92KB
下载 相关 举报
关于网络编程.docx_第1页
第1页 / 共12页
关于网络编程.docx_第2页
第2页 / 共12页
关于网络编程.docx_第3页
第3页 / 共12页
关于网络编程.docx_第4页
第4页 / 共12页
关于网络编程.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

关于网络编程.docx

《关于网络编程.docx》由会员分享,可在线阅读,更多相关《关于网络编程.docx(12页珍藏版)》请在冰豆网上搜索。

关于网络编程.docx

关于网络编程

网络编程是什么?

网络编程是什么?

是熟练使用SocketsAPI吗?

说实话,在实际项目里我只用过两次SocketsAPI,其他时候都是使用封装好的网络库。

第一次是2005年在学校做一个羽毛球赛场计分系统:

我用C#编写运行在PC机上的软件,负责比分的显示;再用C#写了运行在PDA上的计分界面,记分员拿着PDA记录比分;这两部分程序通过TCP协议相互通信。

这其实是个简单的分布式系统,体育馆有不止一片场地,每个场地都有一名拿PDA的记分员,每个场地都有两台显示比分的PC机(显示器是42吋平板电视,放在场地的对角,这样两边看台的观众都能看到比分)。

这两台PC机功能不完全一样,一台只负责显示当前比分,另一台还要负责与PDA通信,并更新数据库里的比分信息。

此外,还有一台PC机负责周期性地从数据库读出全部7片场地的比分,显示在体育馆墙上的大屏幕上。

这台PC上还运行着一个程序,负责生成比分数据的静态页面,通过FTP上传发布到某门户网站的体育频道。

系统中还有一个录入赛程(参赛队,运动员,出场顺序等)数据库的程序,运行在数据库服务器上。

算下来整个系统有十来个程序,运行在二十多台设备(PC和PDA)上,还要考虑可靠性。

将来有机会把这个小系统仔细讲一讲,挺有意思的。

这是我第一次写实际项目中的网络程序,当时写下来的感觉是像写命令行与用户交互的程序:

程序在命令行输出一句提示语,等待客户输入一句话,然后处理客户输入,再输出下一句提示语,如此循环。

只不过这里的“客户”不是人,而是另一个程序。

在建立好TCP连接之后,双方的程序都是read/write循环(为求简单,我用的是blocking读写),直到有一方断开连接。

第二次是2010年编写muduo网络库,我再次拿起了SocketsAPI,写了一个基于Reactor模式的C++网络库。

写这个库的目的之一就是想让日常的网络编程从SocketsAPI的琐碎细节中解脱出来,让程序员专注于业务逻辑,把时间用在刀刃上。

Muduo网络库的示例代码包含了几十个网络程序,这些示例程序都没有直接使用SocketsAPI。

在此之外,无论是实习还是工作,虽然我写的程序都会通过TCP协议与其他程序打交道,但我没有直接使用过SocketsAPI。

对于TCP网络编程,我认为核心是处理“三个半事件”,见《Muduo网络编程示例之零:

前言》中的“TCP网络编程本质论”。

程序员的主要工作是在事件处理函数中实现业务逻辑,而不是和SocketsAPI较劲。

这里还是没有说清楚“网络编程”是什么,请继续阅读后文“网络编程的各种任务角色”。

学习网络编程有用吗?

以上说的是比较底层的网络编程,程序代码直接面对从TCP或UDP收到的数据以及构造数据包发出去。

在实际工作中,另一种常见的情况是通过各种clientlibrary来与服务端打交道,或者在现成的框架中填空来实现server,或者采用更上层的通信方式。

比如用libmemcached与memcached打交道,使用libpq来与PostgreSQL打交道,编写Servlet来响应http请求,使用某种RPC与其他进程通信,等等。

这些情况都会发生网络通信,但不一定算作“网络编程”。

如果你的工作是前面列举的这些,学习TCP/IP网络编程还有用吗?

我认为还是有必要学一学,至少在troubleshooting的时候有用。

无论如何,这些library或framework都会调用底层的SocketsAPI来实现网络功能。

当你的程序遇到一个线上问题,如果你熟悉SocketsAPI,那么从strace不难发现程序卡在哪里,尽管可能你没有直接调用这些SocketsAPI。

另外,熟悉TCP/IP协议、会用tcpdump也大大有助于分析解决线上网络服务问题。

在什么平台上学习网络编程?

对于服务端网络编程,我建议在Linux上学习。

如果在10年前,这个问题的答案或许是FreeBSD,因为FreeBSD根正苗红,在2000年那一次互联网浪潮中扮演了重要角色,是很多公司首选的免费服务器操作系统。

2000年那会儿Linux还远未成熟,连epoll都还没有实现。

(FreeBSD在2001年发布4.1版,加入了kqueue,从此C10k不是问题。

10年后的今天,事情起了变化,Linux成为了市场份额最大的服务器操作系统(http:

//en.wikipedia.org/wiki/Usage_share_of_operating_systems)。

在Linux这种大众系统上学网络编程,遇到什么问题会比较容易解决。

因为用的人多,你遇到的问题别人多半也遇到过;同样因为用的人多,如果真的有什么内核bug,很快就会得到修复,至少有workaround的办法。

如果用别的系统,可能一个问题发到论坛上半个月都不会有人理。

从内核源码的风格看,FreeBSD更干净整洁,注释到位,但是无奈它的市场份额远不如Linux,学习Linux是更好的技术投资。

可移植性重要吗?

写网络程序要不要考虑移植性?

这取决于项目需要,如果贵公司做的程序要卖给其他公司,而对方可能使用Windows、Linux、FreeBSD、Solaris、AIX、HP-UX等等操作系统,这时候考虑移植性。

如果编写公司内部的服务器上用的网络程序,那么大可只关注一个平台,比如Linux。

因为编写和维护可移植的网络程序的代价相当高,平台间的差异可能远比想象中大,即便是POSIX系统之间也有不小的差异(比如Linux没有SO_NOSIGPIPE选项),错误的返回码也大不一样。

我就不打算把muduo往Windows或其他操作系统移植。

如果需要编写可移植的网络程序,我宁愿用libevent或者JavaNetty这样现成的库,把脏活累活留给别人。

网络编程的各种任务角色

计算机网络是个bigtopic,涉及很多人物和角色,既有开发人员,也有运维人员。

比方说:

公司内部两台机器之间ping不通,通常由网络运维人员解决,看看是布线有问题还是路由器设置不对;两台机器能ping通,但是程序连不上,经检查是本机防火墙设置有问题,通常由系统管理员解决;两台机器能连上,但是丢包很严重,发现是网卡或者交换机的网口故障,由硬件维修人员解决;两台机器的程序能连上,但是偶尔发过去的请求得不到响应,通常是程序bug,应该由开发人员解决。

本文主要关心开发人员这一角色。

下面简单列出一些我能想到的跟网络打交道的编程任务,其中前三项是面向网络本身,后面几项是在计算机网络之上构建信息系统。

1.开发网络设备,编写防火墙、交换机、路由器的固件firmware

2.开发或移植网卡的驱动

3.移植或维护TCP/IP协议栈(特别是在嵌入式系统上)

4.开发或维护标准的网络协议程序,HTTP、FTP、DNS、SMTP、POP3、NFS

5.开发标准网络协议的“附加品”,比如HAProxy、squid、varnish等webloadbalancer

6.开发标准或非标准网络服务的客户端库,比如ZooKeeper客户端库,memcached客户端库

7.开发与公司业务直接相关的网络服务程序,比如即时聊天软件的后台服务器,网游服务器,金融交易系统,互联网企业用的分布式海量存储,微博发帖的内部广播通知,等等

8.客户端程序中涉及网络的部分,比如邮件客户端中与POP3、SMTP通信的部分,以及网游的客户端程序中与服务器通信的部分

本文所指的“网络编程”专指第7项,即在TCP/IP协议之上开发业务软件。

面向业务的网络编程的特点

跟开发通用的网络程序不同,开发面向公司业务的专用网络程序有其特点:

·业务逻辑比较复杂,而且时常变化

如果写一个HTTP服务器,在大致实现HTTP/1.1标准之后,程序的主体功能一般不会有太大的变化,程序员会把时间放在性能调优和bug修复上。

而开发针对公司业务的专用程序时,功能说明书(spec)很可能不如HTTP/1.1标准那么细致明确。

更重要的是,程序是快速演化的。

以即时聊天工具的后台服务器为例,可能第一版只支持在线聊天;几个月之后发布第二版,支持离线消息;又过了几个月,第三版支持隐身聊天;随后,第四版支持上传头像;如此等等。

这要求程序员能快速响应新的业务需求,公司才能保持竞争力。

·不一定需要遵循公认的通信协议标准

比方说网游服务器就没什么协议标准,反正客户端和服务端都是本公司开发,如果发现目前的协议设计有问题,两边一起改了就是了。

·程序结构没有定论

对于高并发大吞吐的标准网络服务,一般采用单线程事件驱动的方式开发,比如HAProxy、lighttpd等都是这个模式。

但是对于专用的业务系统,其业务逻辑比较复杂,占用较多的CPU资源,这种单线程事件驱动方式不见得能发挥现在多核处理器的优势。

这留给程序员比较大的自由发挥空间,做好了横扫千军,做烂了一败涂地。

·性能评判的标准不同

如果开发httpd这样的通用服务,必然会和开源的Nginx、lighttpd等高性能服务器比较,程序员要投入相当的精力去优化程序,才能在市场上占有一席之地。

而面向业务的专用网络程序不一定有开源的实现以供对比性能,程序员通常更加注重功能的稳定性与开发的便捷性。

性能只要一代比一代强即可。

·网络编程起到支撑作用,但不处于主导地位

程序员的主要工作是实现业务逻辑,而不只是实现网络通信协议。

这要求程序员深入理解业务。

程序的性能瓶颈不一定在网络上,瓶颈有可能是CPU、DiskIO、数据库等等,这时优化网络方面的代码并不能提高整体性能。

只有对所在的领域有深入的了解,明白各种因素的权衡(trade-off),才能做出一些有针对性的优化。

几个术语

互联网上的很多口水战是由对同一术语的不同理解引起的,比我写的《多线程服务器的适用场合》就曾经人被说是“挂羊头卖狗肉”,因为这篇文章中举的master例子“根本就算不上是个网络服务器。

因为它的瓶颈根本就跟网络无关。

·网络服务器

“网络服务器”这个术语确实含义模糊,到底指硬件还是软件?

到底是服务于网络本身的机器(交换机、路由器、防火墙、NAT),还是利用网络为其他人或程序提供服务的机器(打印服务器、文件服务器、邮件服务器)。

每个人根据自己熟悉的领域,可能会有不同的解读。

比方说或许有人认为只有支持高并发高吞吐的才算是网络服务器。

为了避免无谓的争执,我只用“网络服务程序”或者“网络应用程序”这种含义明确的术语。

“开发网络服务程序”通常不会造成误解。

·客户端?

服务端?

在TCP网络编程里边,客户端和服务端很容易区分,主动发起连接的是客户端,被动接受连接的是服务端。

当然,这个“客户端”本身也可能是个后台服务程序,HTTPProxy对HTTPServer来说就是个客户端。

·客户端编程?

服务端编程?

但是“服务端编程”和“客户端编程”就不那么好区分。

比如Webcrawler,它会主动发起大量连接,扮演的是HTTP客户端的角色,但似乎应该归入“服务端编程”。

又比如写一个HTTPproxy,它既会扮演服务端——被动接受webbrowser发起的连接,也会扮演客户端——主动向HTTPserver发起连接,它究竟算服务端还是客户端?

我猜大多数人会把它归入服务端编程。

那么究竟如何定义“服务端编程”?

服务端编程需要处理大量并发连接?

也许是,也许不是。

比如云风在一篇介绍网游服务器的博客

我认为,“服务端网络编程”指的是编写

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1