应用编程基础课第二讲:网络编程基础

今天给大家介绍下一些网络编程方面的需要掌握的基础知识:

网络分层模型

先来看一张图:

osi-tcp-ip.png

从左到右向,分别是:

  1. OSI七层模型
  2. TCP/IP四层模型
  3. 应用程序实现部分和内核实现部分

这里要认识到的是,我们最常用TCP的网络处理部分,都是由内核来完成的。

TCP服务端和客户端编程模型

TCP连接创建和断开

TCP创建连接需要三次握手,而断开连接需要四次挥手,如图:

tcp-3-4.png

这张图清晰的说明了连接的建立、数据发送以及断开连接时所对应的编程函数,另外还有相应的TCP状态转换。

服务端客户端编程函数

client-server.png

由此可见,服务端编程用到的主要函数为:

  1. socket:创建一个socket,返回的文件描述符fd之后用于bind和listen
  2. bind:绑定socket和ip+port
  3. listen:调用后,服务端状态变为LISTEN,可以接收网络连接
  4. accept:函数在连接建立后返回一个connfd,对这个文件描述符的读写就是在做网络接收和发送
  5. read:网络对端发送来的数据会放到内核的接收缓冲区,read就是从这个缓冲区中读取数据到应用程序
  6. write:应用程序要发送数据到网络对端时,调用此函数,会现将数据写到内核的发送缓冲区中,之后内核会负责将数据发送给网络对端
  7. close:关闭连接

关于服务端的用于连接的fd和用于读写的fd,请见下图:

listenfd.png
connfd.png

客户端编程用到的函数为:

  1. socket:创建一个socket,之后用于连接服务器,做数据读写用
  2. connect:发起到服务端的链接,返回时TCP三次握手完成
  3. write:同服务端的write
  4. read:同服务端的read
  5. close:关闭连接

几个概念

backlog

先附上一个图:

backlog.png

内核中会维护两个队列:

  1. 未完成连接的队列: 服务端收到客户端的连接请求(SYNC),在三次握手完成前,会放到这个队列中
  2. 完成连接的队列:完成三次握手后就创建了一个TCP连接,这个连接会放到这个队列中

linux的man listen中说:

The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow

我理解,backlog定义了未完成连接的队列的最大长度

RTT

这个概念常常听到,请见图:

rtt.png

RTT的定义是Round-Trip Time,即数据包的往返时延

TCP Stream

我们通常说TCP是流式的,这是什么样的概念呢?

socket-stream.png

对应一个TCP连接,内核会给这个连接分配一个发送缓冲和接收缓冲,我们的应用程序对这来两个缓冲区的读写就是在做网络数据的接收和发送。

而数据在网络上的传输是内核自己在维护的,当发送缓冲区中有数据后,内核就把这些数据发送给对端;同样的,当对端有数据过来时,内核会把它放到接收缓冲区中,等待应用程序的读写。

这样的发送和接收数据的过程,就像水流一样,所以我们说TCP是流式的。

TCP状态转换

TCP定义了很多状态,这些状态之间的转换关系如下图:

tcp-status.png

这些状态都记住有难度,需要时查下就好了。

IO模型

网络操作就是IO操作,而且网络的IO是最慢的一种了,网络编程的很大难点就是妥善的处理好这一块的问题。

Unix定义了多种IO操作模型,分别是:

  1. 阻塞IO
  2. 非阻塞IO
  3. IO多路复用
  4. 信号驱动IO
  5. 异步IO

分别说明如下:

阻塞IO

这里有一点非常重要的概念要先说明下,那就是阻塞的是什么?

io-block.png

首先要记住:数据在网络上的传输完全是内核在控制的,应用程序中的read和write只是在读写接收缓冲和发送缓冲。

读阻塞:调用read时,如果接收缓冲区中没有数据,那么就会产生阻塞

写阻塞:调用write时,如果发送缓冲区中的数据没有发送出去,那么就会产生阻塞

那么如果没有产生阻塞,那么两者的执行时间为:

read的执行时间为:将内核接收缓冲区的内容拷贝到用户空间中的应用程序缓冲区

write的执行时间为:将用户空间中的应用程序缓冲区的内容拷贝到内核的发送缓冲区

非阻塞IO

理解了导致阻塞的原因,那么非阻塞就非常好理解了:

io-nonblock.png

当内核缓冲区无法读写时,read和write就会返回EWOULDBLOCK,应用程序就需要过会儿再来操作。

光是这样,还不能实现高性能的网络程序,这是因为我们无法判断应该什么时间再来做读写操作。

如果一直循环读写,那么CPU占用会很居高不下;如果sleep一段时间,那么多长时间合适呢?

所以,如果想开发高性能的网络程序,我们还需要别的武器:

IO多路复用

这是操作系统提供的一种通知机制,告诉应用程序何时可以做读写操作:

io-multiple.png

不同操作系统提供了不同的编程接口,一个非常有名的库libevent就是对这些库的一个统一接口封装。

IO多路复用也是现在用的最多的一种高性能网络服务器的IO处理模型,例如Nginx

信号驱动IO

不同于IO多路复用,操作系统用信号的方式告诉应用程序何时可以做读写操作:

io-signal.png

异步IO

最后这一种我没有用过,从概念上理解,相当于操作系统将数据做完用户空间和内核空间的复制后,才会通知应用程序:

io-async.png

结束语

上面这些,都是笔者编程这些年,觉得非常受用的基础知识。正确的认识这些知识,很多问题你都可以自己想明白了。

笔者也是在不断学习中,如果有错误的地方,还望指正,我们共同进步,谢谢!

参考

UNIX网络编程(卷1):https://book.douban.com/subject/4859464/

TCP/IP详解(卷1):https://book.douban.com/subject/26790659/

Linux/UNIX系统编程手册:https://book.douban.com/subject/25809330/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,640评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,254评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,011评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,755评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,774评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,610评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,352评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,257评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,717评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,894评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,021评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,735评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,354评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,936评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,054评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,224评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,974评论 2 355