11 月 19 - 20 日 Apache Pulsar 社区年度盛会来啦,立即报名! 了解详情
写点什么

网络编程基础知识

  • 2019-11-20
  • 本文字数:2204 字

    阅读完需:约 7 分钟

网络编程基础知识

OpsDev 团队自从九月中旬开启技术分享活动以来,受到了广大技术爱好者的好评,收效显著。第一期公开课由李钢老师开讲,内容为“应用编程基础课”,分为 5 节课,本文为本期的第二节课,重点讲解网络基础编程,包括网络结构、TCP 编程模型和 IO 模型。现整理成文分享出来供大家一起学习。


前言

本人从事 linux 下 web 编程多年,最近有幸给组内同学做培训,希望能够给大家介绍下自己这些年在应用编程方面的经验,今天给大家介绍以下网络编程方面需要掌握的基础知识。


1 网络分层模型

先看一张图:



从左到右向,分别是:


1.OSI 七层模型


2.TCP/IP 四层模型


3.应用程序实现部分和内核实现部分


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


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

TCP 连接创建和断开

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



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


服务端客户端编程函数


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


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,请见下图:



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


1.socket:创建一个 socket,之后用于连接服务器,做数据读写用


2.connect:发起到服务端的链接,返回时 TCP 三次握手完成


3.write:同服务端的 write


4.read:同服务端的 read


5.close:关闭连接


几个概念

backlog


内核中会维护两个队列:


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 的定义是 Round-Trip Time,即数据包的往返时延


TCP Stream

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



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


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


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


TCP 状态转换

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



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


3 IO 模型

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


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


1.阻塞 IO


2.非阻塞 IO


3.IO 多路复用


4.信号驱动 IO


5.异步 IO


阻塞 IO

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



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


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


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


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


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


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


非阻塞 IO

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



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


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


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


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


IO 多路复用

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



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


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


信号驱动 IO

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



异步 IO

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



4 面对如此众多的服务器

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


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


本文转载自公众号 360 云计算(ID:hulktalk)。


原文链接:


https://mp.weixin.qq.com/s/dtmosNh_ej3nGC8suuV6qA


2019-11-20 15:06835

评论

发布
暂无评论
发现更多内容

阿里研究员华先胜:图像搜索的前世今生

阿里技术

为云而生,云原生数据库TDSQL-C技术突破与演进

腾讯云数据库

tdsql 国产数据库

Google I/O 2021 移动和 Web应用上的设备端机器学习

CatTalk

机器学习 tensorflow android Google

开源应用中心|程序员的崩溃瞬间,太形象了!

Java php 开源 插件

云边协同产业方阵成立,中国信通院与 EMQ 共建边缘计算技术规范

EMQ映云科技

物联网 IoT 边缘计算 边云协同

博文推荐|零经验玩转隔离策略:多个 Pulsar 集群

Apache Pulsar

Java 架构 分布式 云原生 Apache Pulsar

从社区贡献者到加入核心团队,开源给他带来了这些变化

TDengine

tdengine 时序数据库

NDPQ(NDP+PQ),定义分布式数据库新方向

华为云开发者联盟

数据库 查询 GaussDB(for MySQL) 近数据处理 NDP

聊聊 ab 和 jmeter 的并发模型

恒生LIGHT云社区

测试 AB

PackML从会到不会——模式(2)

陈的错题集

标准化 PackML

面向容器的资源调度技术对比

阿里技术

安全经典JWT算法漏洞

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

Java SPI 机制从原理到实战

江璇Up

Java spi JavaSPI

大数据开发之Hive

@零度

大数据 hive

云原生数据库TDSQL-C关键技术内核解密

腾讯云数据库

tdsql 国产数据库

使用 Litho 改进 News Feed 上的 Android 视频表现

CatTalk

android facebook 性能优化 Feed流 Litho

技术探究:Apache Pulsar 的事务型事件流

Apache Pulsar

Java 架构 分布式 云原生 Apache Pulsar

一些常用的hive sql函数

编程江湖

大数据 hive Hive SQL

TDSQL演进与突破:把企业级分布式数据库做到极致

腾讯云数据库

tdsql 国产数据库

百度:YOLOX和NanoDet都没我优秀!轻量型实时目标检测模型PP-PicoDet开源

百度开发者中心

目标检测 开源技术

“异地多活”设计辣么难?其实是你想多了!

阿里技术

TDSQL | 国产化浪潮下,数据库+云如何跑上核心业务?

腾讯云数据库

tdsql 国产数据库

很好用的压测工具 - Apache Bench工具

恒生LIGHT云社区

测试 AB AB testing实战

喜报!Nocalhost 成功加入 CNCF 沙箱

CODING DevOps

Kubernetes DevOps cncf Nocalhost 本地化开发

混合云管理策略是什么?如何又快又好的管理混合云?

行云管家

云计算 混合云 云管理

Linux一学就会之文件的基本管理和XFS文件系统备份恢复

学神来啦

Linux 运维 文件系统 linux云计算 linux基础

Python代码阅读(第65篇):根据条件应用指定函数

Felix

Python 编程 Code 阅读代码 Python初学者

魔镜魔镜请回答:FITURE为何上飞书?

ToB行业头条

数据分析从零开始实战,Pandas读取HTML页面+数据处理解析

老表

Python 数据分析 数据处理 11月日更

行云管家Proxy特点及其部署要求详细解析

行云管家

数据库 IT运维 行云管家 跳板机

网络编程基础知识_文化 & 方法_Agang_InfoQ精选文章