socket

我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与 web 服务器通信的?当你用 QQ 聊天时,QQ 进程怎么与服务器或你好友所在的 QQ 进程通信?这些都得靠 socket?那什么是 socket?socket 的类型有哪些?还有 socket 的基本函数,这些都是本文想介绍的。本文的主要内容如下: 1、网络中进程之间如何通信? 2、Socket 是什么? 3、socket 的基本操作 3.1、socket()函数 3.2、bind()函数 3.3、listen()、connect()函数 3.4、accept()函数 3.5、read()、write()函数等 3.6、close()函数 4、socket 中 TCP 的三次握手建立连接详解 5、socket 中 TCP 的四次握手释放连接详解 1、网络中进程之间如何通信? 本地的进程间通信(IPC)有很多种方式,但可以总结为下面 4 类: 消息传递(管道、FIFO、消息队列) 同步(互斥量、条件变量、读写锁、文件和写记录锁、信号量) 共享内存(匿名的和具名的) 远程过程调用(Solaris 门和 Sun RPC) 但这些都不是本文的主题!我们要讨论的是网络中进程之间如何通信?首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!在本地可以通过进程 PID 来唯一标识一个进程,但是在网络中这是行不通的。其实 TCP/IP 协议族已经帮我们解决了这个问题,网络层的“ip 地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip 地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。 使用 TCP/IP 协议的应用程序通常采用应用编程接口:UNIX BSD 的套接字(socket)和 UNIX System V 的 TLI(已经被淘汰),来实现网络进程之间的通信。就目前而言,几乎所有的应用程序都是采用 socket,而现在又是网络时代,网络中进程通信是无处不在,这就是我为什么说“一切皆 socket”。 2、什么是 Socket? 上面我们已经知道网络中的进程是通过 socket 来通信的,那什么是 socket 呢?socket 起源于 Unix,而 Unix/Linux 基本哲学之一就是“一切皆文件”,都可以用“打开 open –> 读写 write/read –> 关闭 close”模式来操作。我的理解就是 Socket 就是该模式的一个实现,socket 即是一种特殊的文件,一些 socket 函数就是对其进行的操作(读/写 IO、打开、关闭),这些函数我们在后面进行介绍。...

March 27, 2022 · 3 min · 564 words · xhwhis

STL

Interview Q&A STL B 树(B-tree)、B+ 树(B+-tree) 特点 一般化的二叉查找树(binary search tree) “矮胖”,内部(非叶子)节点可以拥有可变数量的子节点(数量范围预先定义好) 应用 大部分文件系统、数据库系统都采用 B 树、B+树作为索引结构 区别 B+树中只有叶子节点会带有指向记录的指针(ROWID),而 B 树则所有节点都带有,在内部节点出现的索引项不会再出现在叶子节点。 B+树中所有叶子节点都是通过指针连接在一起,而 B 树不会。 B 树的优点 对于在内部节点的数据,可直接得到,不必根据叶子节点来定位。 B+树的优点 非叶子节点不会带上 ROWID,这样,一个块中可以容纳更多的索引项,一是可以降低树的高度。二是一个内部节点可以定位更多的叶子节点。 叶子节点之间通过指针来连接,范围扫描将十分简单,而对于 B 树来说,则需要在叶子节点和内部节点不停的往返移动。 STL 容器 容器 底层数据结构 时间复杂度 有无序 可不可重复 其他 array 数组 随机读改 O(1) 无序 可重复 支持随机访问 vector 数组 随机读改、尾部插入、尾部删除 O(1) 头部插入、头部删除 O(n) 无序 可重复 支持随机访问 deque 双端队列 头尾插入、头尾删除 O(1) 无序 可重复 一个中央控制器 + 多个缓冲区,支持首尾快速增删,支持随机访问 forward_list 单向链表 插入、删除 O(1) 无序 可重复 不支持随机访问 list 双向链表 插入、删除 O(1) 无序 可重复 不支持随机访问 stack deque / list 顶部插入、顶部删除 O(1) 无序 可重复 deque 或 list 封闭头端开口,不用 vector 的原因应该是容量大小有限制,扩容耗时 queue deque / list 尾部插入、头部删除 O(1) 无序 可重复 deque 或 list 封闭头端开口,不用 vector 的原因应该是容量大小有限制,扩容耗时 priority_queue vector + max-heap 插入、删除 O(log2n) 有序 可重复 vector 容器+heap 处理规则 set 红黑树 插入、删除、查找 O(log2n) 有序 不可重复 multiset 红黑树 插入、删除、查找 O(log2n) 有序 可重复 map 红黑树 插入、删除、查找 O(log2n) 有序 不可重复 multimap 红黑树 插入、删除、查找 O(log2n) 有序 可重复 unordered_set 哈希表 插入、删除、查找 O(1) 最差 O(n) 无序 不可重复 unordered_multiset 哈希表 插入、删除、查找 O(1) 最差 O(n) 无序 可重复 unordered_map 哈希表 插入、删除、查找 O(1) 最差 O(n) 无序 不可重复 unordered_multimap 哈希表 插入、删除、查找 O(1) 最差 O(n) 无序 可重复

March 27, 2022 · 1 min · 173 words · xhwhis

swift学习note

Swift 学习 note Swift 引入 使用 import 语句来引入任何的 Objective-C 框架(或 C 库)到 Swift 程序中。例如 import cocoa 语句导入了使用了 Cocoa 库和 API,可以在 Swift 程序中使用它们。 Cocoa 本身由 Objective-C 语言写成,Objective-C 又是 C 语言的严格超集,所以在 Swift 应用中可以很简单的混入 C 语言代码,甚至是 C++ 代码。 分号 Swift 不要求在每行语句的结尾使用分号(;),但在同一行书写多条语句时,必须用分号隔开: 1 2 import Cocoa var str = "Hello World"; print (str) 词法分析或语法分析时应该直接忽略了分号(;) 标识符 如果一定要使用关键字作为标识符,可以在关键字前后添加重音符号(`),例如: 1 let `class` = "Runoob" 比 php 中的标识符前加@的处理更高级 Swift 空格 Swift 语言并不是像 C/C++,Java 那样完全忽视空格,Swift 对空格的使用有一定的要求,但是又不像 Python 对缩进的要求那么严格。 在 Swift 中,运算符不能直接跟在变量或常量的后面。例如下面的代码会报错:...

March 27, 2022 · 4 min · 760 words · xhwhis

swift学习note——高级篇

Swift 学习 note——高级篇 Swift 闭包 语法 以下定义了一个接收参数并返回指定类型的闭包语法: 1 2 3 {(parameters) -> return type in statements } 实例 1 2 3 4 5 6 7 import Cocoa let divide = {(val1: Int, val2: Int) -> Int in return val1 / val2 } let result = divide(200, 20) print (result) 闭包表达式 闭包表达式是一种利用简洁语法构建内联闭包的方式。 闭包表达式提供了一些语法优化,使得撰写闭包变得简单明了 sorted 方法 Swift 标准库提供了名为 sorted(by:) 的方法,会根据您提供的用于排序的闭包函数将已知类型数组中的值进行排序。 排序完成后,sorted(by:) 方法会返回一个与原数组大小相同,包含同类型元素且元素已正确排序的新数组。原数组不会被 sorted(by:) 方法修改。 sorted(by:)方法需要传入两个参数: 已知类型的数组 闭包函数,该闭包函数需要传入与数组元素类型相同的两个值,并返回一个布尔类型值来表明当排序结束后传入的第一个参数排在第二个参数前面还是后面。如果第一个参数值出现在第二个参数值前面,排序闭包函数需要返回 true,反之返回 false 实例 1 2 3 4 5 6 7 8 9 10 11 import Cocoa let names = ["AT", "AE", "D", "S", "BE"] // 使用普通函数(或内嵌函数)提供排序功能,闭包函数类型需为(String, String) -> Bool。 func backwards(s1: String, s2: String) -> Bool { return s1 > s2 } var reversed = names....

March 27, 2022 · 3 min · 451 words · xhwhis

vim查找&替换

vim 中的查找与替换 1.查找 在 normal 模式下按下/即可进入查找模式,输入要查找的字符串并按下回车。 Vim 会跳转到第一个匹配。按下n查找下一个,按下N查找上一个。 Vim 查找支持正则表达式,例如/vim$匹配行尾的"vim"。 需要查找特殊字符需要转义,例如/vim\$匹配"vim$"。 2.大小写敏感查找 在查找模式中加入\c表示大小写不敏感查找,\C表示大小写敏感查找。例如: /foo\c 将会查找所有的"foo","FOO","Foo"等字符串。 3.大小写敏感配置 Vim 默认采用大小写敏感的查找,为了方便我们常常将其配置为大小写不敏感: " 设置默认进行大小写不敏感查找 set ignorecase " 如果有一个大写字母,则切换到大小写敏感查找 set smartcase 将上述设置粘贴到你的~/.vimrc,重新打开 Vim 即可生效 4.查找当前单词 在 normal 模式下按下*即可查找光标所在单词(word), 要求每次出现的前后为空白字符或标点符号。例如当前为foo, 可以匹配foo bar中的foo,但不可匹配foobar中的foo。 这在查找函数名、变量名时非常有用。 按下g*即可查找光标所在单词的字符序列,每次出现前后字符无要求。 即foo bar和foobar中的foo均可被匹配到。 5.查找与替换 :s(substitute)命令用来查找和替换字符串。语法如下: :{作用范围}s/{目标}/{替换}/{替换标志} 例如:%s/foo/bar/g会在全局范围(%)查找foo并替换为bar,所有出现都会被替换(g) 6.作用范围 作用范围分为当前行、全文、选区等等。 当前行: :s/foo/bar/g 全文: :%s/foo/bar/g 选区,在 Visual 模式下选择区域后输入:,Vim 即可自动补全为 :'<,'>。 :'<,'>s/foo/bar/g 2-11 行: :5,12s/foo/bar/g 当前行.与接下来两行+2: :.,+2s/foo/bar/g 替换标志 上文中命令结尾的g即是替换标志之一,表示全局global替换(即替换目标的所有出现)。 还有很多其他有用的替换标志: 空替换标志表示只替换从光标位置开始,目标的第一次出现: :%s/foo/bar i表示大小写不敏感查找,I表示大小写敏感: :%s/foo/bar/i # 等效于模式中的\c(不敏感)或\C(敏感) :%s/foo\c/bar c表示需要确认,例如全局查找"foo"替换为"bar"并且需要确认:...

March 27, 2022 · 1 min · 88 words · xhwhis