序言
夫功之成,非成于所成之日,盖必有所由起。
——欧阳修
曾经有梦
刚毕业时,面临的第一个大问题就是找工作。北京的竞争是非常激烈的,你一定是领教过的,如果还没有,总有一天你会知道。我所学的是冷门专业,想在北京找一份像样的工作是非常难的。所以决定利用在研究生期间自学的计算机知识找一份与计算机相关的工作,也不知道要找哪个方向,简历上把知道的全写上了,招聘会上见到与计算机相关的单位就投简历,经过了无数次的被拒绝后,天意垂顾,最后通过了中国科学院软件中心的笔试和面试,被录用了。
入职后我被分配到了网络协议部门,顾名思义,就是手机上TCP/IP及相关网络协议的开发。最早接触的工作就是用套接口(socket)编写程序,我是第一次接触socket,还不知道它是做什么的,茫然失措。到书店买本书看看吧,苦苦寻找了一天,也没找到一本合适的。直接介绍WinSock的书少之又少,只能先选一本回去参考。可是这本书,只是对MSDN上WinSock相关函数的简单翻译,加上几个小例子。看了之后,还是不明白,仿佛一个迷途的人遇到了一个老乡,上前问路,却怎么也说不清楚。我需要的不是对函数的简单说明,而是怎样把socket提供的接口函数有机结合起来,编写一个适用的网络程序。
于是我决定写一本这样的书。十年来,我学习了上千页的网络技术标准(RFC、OMA技术规范等)、几百篇的论文、二百多本的技术和非技术书籍、密密麻麻的笔记,无数雪花般纷飞的纸页,终于会聚在一起,就是你今天拿到的这本书。
博览群书、日积月累的渐悟之后,很多原理、规范,现在看来都是理所当然的。但我并没有忘记初学时的痛苦、困惑,为此,把我学习过程中的心得如实地记录下来,为后学者铺就一条通往知识高峰的道路。
写作一本WinSock网络编程的书,是我多年的梦想。写作的过程是艰辛的,我没有整块的时间来支配,只能每天写一点儿,有时甚至几个星期也没有时间写,进度非常慢。而且随着工作越来越忙,可支配的时间越来越少,曾几何时,这似乎已经是遥不可及了。
逝者如斯夫,莘莘学子已经人到中年,梳洗时,常常凝望镜中的我,两鬓已有了斑白的发。忽然会记起还没能实现的梦想,心中涌出一种无法解释的悲伤。暗暗鼓起勇气、还是努力坚持,终于,走过了最艰难的岁月,把这本书写完了,将与广大读者一起梳理WinSock网络编程的经络。
这本书的写作,90%以上的内容都是在夜里完成的,写作的时间一般是晚上9点至深夜1点。经常是写累了,躺在床上休息一会儿,不知不觉就睡着了。醒后,灯还亮着,电脑还没有关,于是又接着写……常常,在静静的午夜,找寻创作的灵感,却在睡梦惊醒时,蓦然瞥见绝美的月光。
我希望为读者奉献一桌WinSock编程的饕餮大餐,但每个人的胃口都不一样,需要品尝后方才知道是否适合你。尽吾志也尔不能至者,可以无悔矣,其孰能讥之乎?
“在我心中,曾经有一个梦,要用本书让你忘了网络编程的痛,灿烂星空,谁是真的英雄……”
写作风格
写作过程中,参考了大量的英文文献,计算机书籍中最大的阅读障碍在于许多技术名词或专业术语没有标准的译名,大量的译作或著作都按自己的理解来翻译,结果造成读者的困惑,甚至不知所云。
我是一名软件工程师,多年从事软件开发,以阅读英文文献为主,希望这本书中出现的名词或术语不会给各位造成迷惑,读来通顺流畅。在每一个名词或术语出现之处,首先是全称及缩写,后面给出了翻译,这么做不是画蛇添足,只是方便读者对照阅读,知道原始内容为何。也能让有探索精神的读者去仔细斟酌,万一是我错了呢,人非尧舜,谁能尽善?
文中出现的许多引用,即使有多本著作都是那么写的,笔者还是会不辞辛劳地查找原始参考文献,以了解它最初的意义,也以怀疑和批判的态度校正那些著作中可能出现的错误。
术语IEN,在很多TCP/IP或者网络相关的书籍中,如:《TCP/IP指南(卷1),底层核心协议》和《用TCP/IP进行网际互联,第一卷:原理、协议与结构》都被写为Internet Engineering Notes,翻译为“互联网工程便笺”。这两本书虽然都是这一领域中的经典之作,但作者并没有因此而简单地盲从。先在网上搜索这一术语的出处,没有找到,想到既然这是网络早期的文档,应该在最早的RFC中有,于是阅读了多篇RFC,发现在引用处也是只有缩写,没有全称,后来终于在一篇描述RFC历史的文档RFC 2555中找到了它的全称Internet Experiment Notes (IEN),在文中我把它译为“互联网实验记录”。事不目见耳闻,而臆断其有无,可乎?
读者对象
拿到这本书,相当于请了一位辅导老师。书中的内容是按照新手的学习过程安排的,循序渐进,先讲基础知识、设计原理,再讲程序设计,并对程序的代码逐行讲解。对于每个知识点,尽量提供足够的信息,使它能够被稍微有些程序设计经验的程序员所接受。定位的读者对象是初、中级C、C++网络程序员。只要掌握了WinSock各个函数的正确用法,即使不完全理解底层协议的运作原理,也不妨碍你设计一个正确的网络程序。
对于高级的网络程序员,本书也值得借鉴。程序中用到的每一个WinSock函数,我都编写程序做了许多测试实验,以了解它的实现机制,交互原理,并指出了一些函数存在的陷阱。书中提供的是对底层协议及WinSock编程每一个技术细节的深入研究,许多主题在目前出版的同类书籍中是没有的或者有也没有本书深入。呵呵,真的!工作的前四年内我就在业余时间阅读了Xinu、FreeBSD及Linux操作系统的TCP/IP及socket源代码,而且封装过多个平台的socket编程接口,这个领域,举目四望,一览众山小。与其他书籍不同的是,书中不仅介绍正确的解题方法,也会告诉你我走过的歧路,我已经跌倒了一次,你就不必再经历同样的痛苦了。
操作系统当然要用Windows了,书中的程序都在Windows XP和Vista上做了测试。编码、编译、调试程序使用的是Visual C++ 6.0集成开发环境。阅读本书,需要读者具备C语言的基本知识,至少看过一两本C语言书籍。本书不会介绍C语言的数据类型、表达式、语法规则等,假设你已经可以熟练使用C语言,并用它编写程序。对C语言还不熟悉的读者,可以参考Brian W.Kernighan, Dennis M. Ritchie编写的《C语言程序设计》和Peter Van Der Linden的《C专家编程》,它们都是学习C语言很好的参考资料。最后几章在讲解WinSock异步编程时,会用到Windows SDK,书中对用Windows SDK编程做了简单的介绍,足以让你理解相关的例子。想对Windows编程有更深入的理解,可以参考Charles Petzold的《Windows程序设计》,已经出版到第五版,被誉为Windows编程圣经。
内容介绍
书的名字已经做了自我说明,主要讲解WinSock网络编程。WinSock是Windows操作系统上的网络编程接口,基于BSD socket模型。它包含了与BSD socket同名的接口函数,用法与BSD socket编程接口是一致的,但为了充分利用Windows的特性,结合Windows的消息机制,WinSock增加了许多扩展函数。
WinSock有两个版本,1.1和2.2,1.1在1993年发布,只支持TCP/IP协议栈,1996年发布了2.2,它完全兼容1.1,但它支持多种协议,是1.1的一个超集。WinSock 2.2提供了独立于协议的传输接口,能够支持多种协议,如OSI、Novel IPX/SPX、Digital 's DECNet等。而且允许用标准的方法增加新的协议。
本书讲解的WinSock版本是2.2,但不是介绍WinSock 2.2规范中列出的所有API,而主要说明的是2.2版本中与1.1兼容的部分。根据笔者的实践经验,WinSock 1.1完全满足一般的网络应用开发,到目前为止我还没有遇到一定要用WinSock 2.2新增加的API才能解决的问题。重要的是WinSock 1.1与BSD socket基本上是兼容的,而2.2版本中新增加的API与BSD socket完全不兼容。网络上有很多基于Linux或UNIX系统的开源项目,这些程序中涉及网络部分的源代码使用的都是BSD socket,当把它移植到Windows系统上时,使用的都是WinSock 1.1提供的API。
书的内容总体上分为两大部分:网络基础和程序设计。
网络基础部分先让大家知道什么是网络,它的功能是什么,网络的分类、交换技术及参考模型。有了总体的认识后,重点讲解互联网中被广泛使用的TCP/IP协议,它是整个互联网得以运行的基础。书中会说明TCP/IP协议的标准化过程、模型、架构等。随后在相关章节中分别介绍TCP/IP每一层所使用的协议。
程序设计部分先介绍WinSock的基础知识,WinSock的版本、与BSD socket的差别、编程模型,再介绍一些常用的转换函数及域名解析,这些是后面程序设计最常用的工具函数。接下来的几章是根据WinSock的特性分别讲解,如TCP、UDP、原始套接口、多播、广播等,每一章都是先介绍基本原理,再给出例子程序,并对程序做详细的说明。
本书特色
写作的重点是要教你如何设计一个实用的网络程序,如果你想真正理解互联网的工作原理,并想开发出在互联网上运行的应用程序,请选择本书。如果你想要自己搭建网络,把家中或公司的PC或服务器连接起来,本书不适合你。
作为一名工作多年的程序员,我也一直在不断地学习新的知识,我对自己的要求是工作之外每年至少阅读十二本技术书籍,一个月一本。深知初学者学习新知识时遇到的各种困难、迷惑,所以本书按照初学者的学习过程安排,对协议的原理、函数的功能、程序的代码都做了非常详尽的介绍。记得我在读算法设计书时,有时书的作者理所当然地就给出了结论,可是我怎么也不明白,反复阅读、仔细推敲后才终于醒悟,原来如此。这些书的作者都是这一领域的专家,有很多对他们来说是足够简单的问题,可读者却未必明白。所以本书宁可啰嗦一些,也不漏掉每一个细节。
理论与实践结合
计算机技术既具有很强的理论性,又具有很强的实践性。要求我们掌握好理论知识,并把它应用到程序设计的实践中去,在实践中发现问题、解决问题。最有效的学习方法就是实践。程序设计篇章中提供了许多示例,有服务器程序,也有客户端的程序,读者可以先运行程序,看一下实际的效果,有了感性的认识后,再阅读代码、调试程序或者修改代码来测试一些函数的行为,在实践中提高程序设计的能力。
经典应用
在互联网发展的过程中,为了满足不同的需要,制定了各种各样的协议。书中的示例不是随意编造的,而是选择实用的网络程序,如Ping、TraceRoute等,或选取标准的网络协议,如Echo、Daytime、Finger、HTTP、FTP等,它们都是为了辅助读者理解WinSock的功能。另外,选用这些协议也扩展了知识面,让读者理解互联网上一些标准协议的工作原理,如SNTP、FTP、HTTP等,是目前仍然被广泛使用的网络协议。书中简化了许多细节,只保留协议最本质的东西,用尽量少的代码实现这些协议,掌握了这些知识,你也就知道真正的协议是如何工作的了。这在当前所出版的同类书籍中是没有的,本书填补了这一领域的空白。
详细的插图
为了帮助读者理解编程模型、协议原理、程序流程,书中绘制了大量的插图,几乎每一章都不少于两幅。图的下方有简短的文字说明,让读者快速了解图的含义。书中也对图配有辅助性的文字描述,帮助读者理解难懂的概念。
感恩的心
写作过程中,龙飞凤舞,只求先把思想表达出来。写完了,想到书一旦付梓出版,不知面对多少读者,一点点的错误也会引起误解,为了不误人子弟,怀着诚惶诚恐的心情,又从头至尾仔细地校对,改正了若干拼写错误。每次发现错误的时候,我都亦喜亦忧,喜的是书中的错误又少了一个,忧的是不知还有多少错误没有发现。所有的程序编写完,都做了仔细的测试,确保它们可以正确运行。
作者已经在这一领域深耕多年,但互联网是一个庞大的知识体系,RFC的编号已经到了6400多,我所掌握的只是其中的一小部分。WinSock不是开放源代码的,我没有学习过它的源代码,书中的很多结论都是通过实验得出的。我所做的也不是开创性的工作,只是把前人解决的问题向大家讲清楚而已。吾生也有涯,而知也无涯。由于笔者能力和水平的限制,书中难免会有纰漏和错误,请读者批评指正。
以前阅读书籍时,快的一两周就看完了,慢的也就五六周,从没想过作者的辛苦。当自己开始写作时,才发现这是一个艰辛、漫长的过程,需要有持久的恒心、坚强的毅力。经过了不知道多少个漫漫孤寂的黑夜,有时连我自己都不知道本书是否还能够完成。
今天你拿到了它,阅读本书,当你遇到错误时,请给我一个温暖的笑容、一句善意的批评。同是人,皆需爱。欢迎你对本书的内容提出建议,反馈给我,不管是抱怨还是称赞,我将欣然接受,并回答与使用本书直接相关的问题。可通过下面的地址与我联系:zhang.huiyong@yahoo.com。
从小到大我们阅读了无数的书籍,从这些书里我们获取知识、增长见识。在每个人成长的过程中,都有那么多不曾熟识的作者默默地奉献着。想到有一天,自己具备了这样的能力,也要把我所知道的回馈给社会,今天终于有了一个这样的机会。2月的北京,窗外依然寒冷,但我的心里却充满了春天的气息!
如果说今天的我已经取得了一点成绩,那是母亲用她辛勤的汗水为我铺就了前进的阶梯,感谢她给我的无私而伟大的母爱。感谢妻子,分担了许多家务,尽心地辅导女儿,让我能够努力工作、专心写作。在人生的道路上我们相呴以湿,相濡以沫。感谢女儿,她的出生使我懂得了做父亲的责任,看着她一天天的长大,心里洋溢着幸福,与她在一起,总是我最快乐的时光。
张会勇
2012年2月于北京中关村