陈硕《网络编程实战》

01 网络编程概要

站在巨人的肩膀之上。

按照录像整理,部分专有名词不太肯定,版权归陈硕大神。

大家好,我是陈硕,受邀讲授一门有关网络编程的在线课程,这门课程的名称是《网络编程实战》,主要通过讲解十多个例子,展示网络编程的一些常用技法。

《UNIX网络编程》是理查德.斯蒂文斯的传世之作,本课程认为你已经大致读过本书,具备基本的TCP/IP知识,例如IP地址端口号等等,而且用Sockets API 写过echo Sever 这样简单的网络程序,这是这门课程的前提条件。

本课程针对的是 Linux 系统,使用 C++、Python、Go 几门语言,其中 C++ 用的最多。

理查德.史蒂文斯在1990年出版了《UNIX网络编程》的第一版,之后他写了《UNIX环境高级编程》和《TCP/IP详解》 三卷本。

然后他开始写《UNIX网络编程》第二版,原计划分三卷出版:

第一卷讲网络编程API,1998年出版,这本书主要讲的是Sockets APIs,他也讲了现在已经淘汰了的XTI,这个不去谈它;

第二卷其实和网络编程关系不大,主要讲进程间通信,1999年出版,你可以认为是讲多进程和多线程的并发编程,这两本书都是用 C 语言;

第三卷最令人期待的一本书,讲网络编程的应用,可惜,理查德.斯蒂文斯1999年9月1号不幸去世,本书就没有下文了。

当然了,我这门课程不是想续上《UNIX网络编程》第三卷,而是补充一些实际的编程例子,帮助读者更好地掌握《UNIX网络编程》第一卷的内容。

我认为,《UNIX网络编程》第一卷有两样东西强调的不够:

第一个是消息格式的处理,特别是在非阻塞IO下如何正确的处理TCP分包这个没有讲到。

第二个呢,是这本书讲授的并发模型稍显陈旧,高并发服务往往采用事务驱动加非阻塞IO的办法,这是传统的,在《UNIX网络编程》中,分量不足,只有一章,而有一本书专门讲这方面内容,是叫《面向模式的软件架构》第二卷,讲各种并发模型,因此本门课程也会参考这本书,这本书是2000年出版的。

《UNIX网络编程》第三版是由另外一个人续写的,在2003年出版,如果你要去买书的话,可以考虑买他的第三版。

本课程名为《网络编程实战》,有十多个代码示例,而且会分析代码背后的道理,这门课程主要针对服务端的 TCP 网络编程,基本不涉及客户端,也就不涉及图形用户界面、APP等等。但会讲TCP客户端,但不是那种很用户交互的客户端,只会略微提到UDP,会讲UDP和TCP编程的巨大区别,特别在处理并发方面的手法是完全不同的。

一说起网络编程,很多人就往高性能上想,而这门课程强调的是可以测量的性能,测不出来的性能指标是没有意义的,还有呢,我想避免那种基于猜测、猜想的优化,因为我发现有些优化,除了让代码变得更复杂而难以维护之外,对性能没有实质的提升,网络编程有很多以讹传讹的讲究,在一些中文论坛上面看出来,比如民间传说要尽量减少动态内存分配,使用STL更是罪大恶极,但是你知道Linux内核,从网卡收到一个数据包到经过协议栈把数据传给应用程序,这个过程中一共会分配释放多少次内存呢?

你知道网络是分层的,一般程序员关注四层:以太网层,IP层、传输层和应用层。

我们在谈几层的时候,术语要准确,以太网 Frame 叫帧,IP Packet 叫分组,TCP segment叫分节,应用层通常我们谈消息(message),注意“IP的分组”和“IP的分片”是两个事情,一般我们不用管IP分片。

网络编程是一个入门容易精通难的事情,初学者有一些常见的错误,这里列了一些,在后面的课程中还会具体的结合例子来讲,这里先大致提一下:

一个是《UNIX网络编程》的示例代码,往往把网络IO和业务逻辑穿插在一起,这固然比较容易写出紧凑易读的代码,但是在大型项目中,这种做法的可维护性比较低,因为不是每个人都那么精通网络编程的方方面面的细节,如果他熟悉业务逻辑,那他在写业务逻辑的时候,可能一不小心就引入网络编程方面的Bug,应该是尽量避免在网络编程中把和Socket API 打交道代码和业务逻辑穿插在一起。

第二个呢,也是中文论坛上,长期出现的项目,有人说TCP不可靠,收到的数据不完整,这个话题以后我还会专门讲,主要是涉及TCP连接断开的时机与条件,Close太早的话,有可能导致协议栈发送RST分节,将连接重置,数据自然就收不完了,在阻塞编程中可以使用SO_LINGER这个选项,在非阻塞SO_LINGER这个选项没用,我们现在从应用层的协议上入手解决问题,你在设计应用层协议的时候,把TCP连接的断开,要放到协议设计的考虑当中去。

第三个呢,TCP是一个字节流协议,他保证字节按顺序到达,但不保留消息的边界,因为对于TCP本身来说没有消息概念,就说你发送一堆的数据过去。那么,TCP我们检测程序的一个办法,就是如果他一个字节一个字节收到的话,你程序应该也能正常工作。在应用程序中,我们要设计并实现TCP分包的逻辑,把TCP的字节流切分成一个一个可以分开的消息,这方面有一些小坑,初学者容易掉进去,课程以后会讲到。

第四个呢,初学者常见的一个设计失误,直接发送C语言的结构体,这个问题有两个:

第一个呢,他要考虑对齐,有的人会直接修改全局的对齐的方式,他把pack设成1,直接导致第三方library扩大,因为破坏了API二进制接口;

还有问题是在于,高度的不可扩展。因为你要增加一个字段的话,就所有的客户端服务端都要升级,而且如果有一方不是用C语言写的话,你就要手工实现 pack、unpack 的代码,也是维护上有很大的代价,这么做就一开始用发送C strcut,可能是受了学TCP的教材的影响,因为TCP/IP的header,它就用的是定长的那种字段的格式,而且它里面用了Bit field(位域),所以可能有的人照猫画虎说,既然TCP/IP自己这么用,那我自己写应用的时候也是用struct来表示消息,这个情况我认为通常应该避免的。

第五个是一个具体的小坑,就是TCP的“自连接”。你发现TCP的客户端往本机的服务端发起连接的时候,如果服务器没有起来,在一定条件下,客户端会自己和自己建立一个连接,比方说从localhost的端口54321,再连到了54321端口,你收发数据出现鬼打墙的现象,发个数据,自己收回来,就跟出现loop循环编程的时候一样,你知道现象就很很好办,你发现种情况就把连接断开,重新试就行了。

最后呢,非阻塞网络编程中还有很多很多坑,一个好的库呢,应该把大多数坑都填上,同时程序员,你要明白非阻塞网络编程的特点,避免别人把坑填好了,你自己再把坑挖开掉进去。

现在千兆网早就普及了,在很多机房里面,万兆网,实际的以太网也已经不堪使用,那么你很自然的想法,千兆网到底有多快?如果我们用TCP来传输数据的话,这里有简单的计算,它把从以太网的层面消息的每部分的长度列出来,算出来一个最大的带宽是117兆字节每秒,或者用二进制的 Mega,bit 计算的话是112,下面我们先来做个实验,验证一下计算是否正确。

陈硕《网络编程实战》01 网络编程概要相关推荐

  1. c++并发编程实战_Java 并发编程实战:JAVA中断线程几种基本方法

    一个多线程Java程序,只有当其全部线程执行结束时(更具体地说,是所有非守护线程结束或者某个线程调用system.exit()方法的时候) ,才会结束运行.有时,为了终止程序或者取消一个线程对象所执行 ...

  2. C++多线程编程实战01:std::thread

    C++多线程:std::thread 文章目录 C++多线程:std::thread 定义 构造函数 析构函数 赋值操作函数 join与datch 例子 例子 其它 基本用法 线程参数 等待线程完成( ...

  3. Linux下的C编程实战之文件系统编程

    在Linux平台下对文件编程可以使用两类函数:(1)Linux操作系统文件API:(2)C语言I/O库函数.前者依赖于Linux系统调用,后者实际上与操作系统是独立的,因为在任何操作系统下,使用C语言 ...

  4. Java并发编程实战笔记—— 并发编程1

    1.如何创建并运行java线程 创建一个线程可以继承java的Thread类,或者实现Runnabe接口. public class thread {static class MyThread1 ex ...

  5. linux 蓝牙编程,实战Linux Bluetooth编程(三) HCI层编程

    1. HCI层协议概述: HCI提供一套统一的方法来访问Bluetooth底层.如图所示: 从图上可以看出,Host Controller Interface(HCI)  就是用来沟通Host和Mod ...

  6. 陈硕《网络编程实战》00 前言

    陈硕<网络编程实战> 第 00 课 前言 站在巨人的肩膀之上,还要抓牢,不要掉下去.    按照录像整理,版权归陈硕大神. 作者简介: 陈硕,北京师范大学硕士,擅长 C++ 多线程网络编程 ...

  7. NIO网络编程实战之简单多人聊天室

    NIO网络编程实战 利用NIO编程知识,实现多人聊天室. 1. NIO编程实现步骤 第一步:创建Selector 第二步:创建ServerSocketChannel,并绑定监听端口 第三步:将Chan ...

  8. 陈硕《网络编程实战》目录

    陈硕<网络编程实战>目录 00.前言 01.网络编程概要.mkv 02.一个TCP的简单实验.mkv 03.课程内容大纲.mkv 04.回顾基础的Sockets API.mkv 05.TT ...

  9. 陈硕《网络编程实战》 84 课程总结 【草稿】

    陈硕<网络编程实战> 84 课程总结 [草稿] 站在巨人的肩膀之上. 按照录像整理,版权归陈硕大神. 我们这门课程呢,今天就是最后一讲,已经讲完了. 那我们再做一点小结,整理一下这个思路: ...

最新文章

  1. Linux之Redis安装
  2. 工作中必须要知道的git高级用法
  3. java ssm框架详解_Java的SSM框架怎样才算真正掌握?
  4. Java黑皮书课后题第5章:*5.24(数列求和)编写程序,计算下面数列的和:1/3+3/5+5/7+7/9+……95/97+97/99
  5. Android中Application类用法
  6. documentbodyscrollTop的值总为零的解决办法
  7. 《Essential C++》笔记之文件读写示例
  8. SSM SpringBoot vue教务排课系统
  9. COMSOL Multiphysics 多物理场仿真学习小记
  10. PHP内容管理系统详细制作步骤
  11. FigDraw 1. SCI 文章的灵魂 之 简约优雅的图表配色
  12. 热门小说排行榜(JSP实现)
  13. 新手用canvas画时钟
  14. 爱词霸汉语站联合多家官方媒体发布中国十大流行语
  15. 格式工厂转码错误原因0x000000001 怎么办
  16. (FortiGate)飞塔防火墙配置AD***
  17. C#进行Visio二次开发之Web查看Visio图纸
  18. 哔!与刷卡机贴贴的付款卡经历了什么?
  19. 六年级计算机应用计划,《小学信息技术》六年级下册教学计划
  20. linux系统在线安装报E错无法定位安装包,两种解决办法,一是更换软件源,二是离线官网下载安装包安装

热门文章

  1. matlab学习 函数句柄(函数的间接调用方法)
  2. 关系型数据库与非关系数据库区别
  3. Libreoffice安装配置,office文件转PDF
  4. 详解scheduleAtFixedRate 与 scheduleWithFixedDelay 的区别
  5. 简析Java中的Serializable与Android中的Parcelable序列化
  6. 飞翼布局短垂起降飞机概念设计--“彩鸿22”舰载无人机
  7. 云原生之使用Docker部署OneNav个人书签管理器
  8. 进程和线程的详解和区别
  9. 鸿蒙试炼怎么玩,诛仙3鸿蒙试炼玩法介绍
  10. 计算机语言中的次方,浅谈Go语言中的次方用法