meowrain

MeowRain

Life is Simple

Vim操作

编辑模式下: ctrl + h删除上一个字符 ctrl + w 删除上一个单词 ctrl + u 删除当前行 ctrl + o 进入单词命令模式 ctrl + [ 退出编辑模式 进入Normal模式 Normal Mode: r 替换字符 ra会把光标所在的字符替换为a s 删除字符并进入编辑模式 R 不断的替换后面的字符,进入replace模式 S 删除当前整行,进入编辑模式 a在当前字符后面添加进入编辑模式 i 进入编辑模式 o 新开一行进入编辑模式 x 删除后面的一个字符 dd删除当前行 dt)删除括号中的内容 delete until ) dt " 删除双引号中的内容 d$ 从当前光标位置删除到行尾 ct) 删除括号中的内容,并进入插入模式 ct" 删除双引号中的内容并进入插入模式 c$ 和S的效果相同,删除当前行并进入插入模式 yy复制整行 p 粘贴 v 进入visual模式,选中文本,按y进行复制 A 跳转到当前行末尾,在当前行末尾添加字符,进入编辑模式 I 跳转到当前行开头,进入编辑模式 O 在当前行的上一行新开一行,进入编辑模式 gi 快速跳转到你最后一次编辑的地方并进入插入模式 dw 删除一个单词 cw 删除一个单词并进入编辑模式

HTTP升级为websocket

理解HTTP如何升级为WebSocket需要了解一些协议层面的细节。WebSocket是基于HTTP协议的一个扩展,它允许客户端和服务器之间进行全双工通信。以下是详细的升级过程原理: 升级过程原理 HTTP请求握手: WebSocket连接始于一个HTTP请求,它包含特殊的头部字段,这些字段请求服务器升级连接到WebSocket协议。 客户端发送升级请求: 客户端发送一个HTTP GET请求到服务器,并在请求头中包含以下字段: Upgrade: websocket:表示请求升级到WebSocket协议。 Connection: Upgrade:表示客户端希望升级连接。 Sec-WebSocket-Key:一个Base64编码的随机字符串,用于服务器生成响应。 Sec-WebSocket-Version:WebSocket协议版本,一般为13。 示例请求: 1 2 3 4 5 6 GET /chat HTTP/1.1 Host: example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Version: 13 服务器处理升级请求: 服务器收到升级请求后,检查请求头以确保它们包含正确的值。如果请求有效,服务器生成一个响应以完成升级。 服务器生成Sec-WebSocket-Accept值: 取Sec-WebSocket-Key的值。 连接一个固定的字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11。 对连接后的字符串进行SHA-1哈希计算。 对哈希结果进行Base64编码。 服务器响应升级请求: 服务器发送一个HTTP 101响应,表示协议切换,并在响应头中包含以下字段: Upgrade: websocket:确认协议升级。 Connection: Upgrade:确认协议升级。 Sec-WebSocket-Accept:包含服务器生成的接受密钥。 示例响应: 1 2 3 4 HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= 建立WebSocket连接: 一旦服务器发送HTTP 101响应,连接正式升级为WebSocket协议,客户端和服务器可以开始通过WebSocket进行全双工通信。 代码实现示例 以下是一个简单的Go示例,展示如何实现HTTP到WebSocket的升级: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 package main import ( "log" "net/http" "sync" "github.

Socks5协议实现

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 package main import ( "bufio" "encoding/binary" "errors" "fmt" "io" "log" "net" "sync" ) const socks5Version = 0x05 const subnegotiation = 0x01 const connectCommand = 0x01 const bindCommand = 0x02 const udpAssociateCommand = 0x03 const ipv4AddressType = 0x01 const ipv6AddressType = 0x04 const domainAddressType = 0x03 func main() { server, err := net.

在网页中实现退出前询问用户是否保存更改的功能

在网页中实现退出前询问用户是否保存更改的功能,通常使用的是 JavaScript 的 window.onbeforeunload 事件。这个事件会在窗口、文档和资源即将被卸载时触发,可以用来提示用户是否有未保存的更改。 以下是一个简单的示例代码,展示如何在用户尝试离开页面时弹出确认对话框: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Before Unload Example</title> </head> <body> <script> window.addEventListener('beforeunload', function (event) { // 取消浏览器默认行为,即显示默认的确认消息框 event.preventDefault(); // 在现代浏览器中,需要设置返回值以自定义确认消息 event.returnValue = '您有未保存的更改,确定要离开吗?'; }); </script> </body> </html> 这段代码会监听 beforeunload 事件,并在事件触发时阻止浏览器的默认行为,同时返回一个自定义的确认消息。这样,当用户试图关闭标签页或导航到其他页面时,浏览器会弹出一个确认对话框,询问用户是否真的要离开。 需要注意的是,不同的浏览器可能对 beforeunload 事件的处理方式有所不同。例如,在某些浏览器中,你可能只能看到一个默认的消息,而无法看到上面代码中自定义的返回值。因此,为了确保兼容性,你可能需要检查特定浏览器的行为并进行相应的调整。 此外,如果你的应用中有更复杂的表单或者状态管理,可能需要在表单提交或状态更改时动态地启用或禁用此监听器,以避免不必要的警告。

Socks5协议详解

socks协议介绍 啥是socks协议呢? 这里贴一段维基百科对它的定义 SOCKS is an Internet protocol that exchanges network packets between a client and server through a proxy server 大概的意思是: socks是一种互联网协议,它通过一个代理服务器在客户端和服务端之间交换网络数据。简单来说,它就是一种代理协议,扮演一个中间人的角色,在客户端和目标主机之间转发数据。 socks协议位于OSI模型中的第五层,即会话层(Session Layer)。 socks相当于在防火墙撕了一道口子,让合法的用户可以通过这个口子连接到内部,从而访问内部的一些资源和进行管理。 socks5顾名思义就是socks协议的第五个版本,作为socks4的一个延伸,在socks4的基础上新增UDP转发和认证功能。唯一遗憾的是socks5并不兼容socks4协议。socks5由IETF在1996年正式发布,经过这么多年的发展,互联网上基本上都以socks5为主,socks4已经退出了历史的舞台。 工作过程 1.握手阶段 1.1 协商阶段 第一步,客户端向代理服务器发送代理请求,其中包含了代理的版本和认证方式 1 2 3 4 5 6 7 +----+----------+----------+ |VER | NMETHODS | METHODS | +----+----------+----------+ | 1 | 1 | 1 to 255 | +----+----------+----------+ #上方的数字表示字节数,下面的表格同理,不再赘述 VER: 协议版本,socks5为0x05 NMETHODS: 支持认证的方法数量 METHODS: 对应NMETHODS,NMETHODS的值为多少,METHODS就有多少个字节。 第二个字段NMETHODS表示支持的认证方式,第三个字段是一个数组,包含了支持的认证方式列表: RFC预定义了一些值的含义,内容如下: 0x00: 不需要认证 0x01: GSSAPI认证 0x02: 用户名和密码方式认证 0x03: IANA认证 0x80-0xfe: 保留的认证方式 0xff: 不支持任何认证方式 socks5服务器需要选中一个METHOD返回给客户端,格式如下:

Go设计模式

Golang设计模式 一.面向对象设计原则 1.1 单一职责原则 类的职责单一,对外只提供一种功能,而引起类变化的原因都应该只有一个。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 //不遵守单一职责原则 package main import "fmt" /* 在这个例子中,Clothes 类包含了两个方法 onWork() 和 onShop(),这两个方法描述了在不同场景下(工作和购物)穿着相同的装扮。 问题在于这两种场景虽然使用了相同的装扮, 但它们实际上是两种不同的行为或上下文。 */ type Clothes struct{} func (c *Clothes) onWork() { fmt.Println("工作的装扮") } func (c *Clothes) onShop() { fmt.Println("购物的装扮") } func main() { c := Clothes{} //逛街的业务 c.onShop() //工作的业务 c.

Go垃圾回收机制

Go GC机制 5、Golang三色标记混合写屏障GC模式全分析 (yuque.com) 垃圾回收(Garbage Collection,简称GC)是编程语言中提供的自动的内存管理机制,自动释放不需要的内存对象,让出存储器资源。GC过程中无需程序员手动执行。GC机制在现代很多编程语言都支持,GC能力的性能与优劣也是不同语言之间对比度指标之一。 发展过程 Go V1.3之前的标记-清除(mark and sweep)算法,Go V1.3之前的标记-清扫(mark and sweep)的缺点 Go V1.3之前的标记-清除(mark and sweep)算法 接下来我们来看一下在Golang1.3之前的时候主要用的普通的标记-清除算法,此算法主要有两个主要的步骤: 标记(Mark phase) 清除(Sweep phase) STW会对可达对象做上标记,然后对不可达对象进行GC回收 操作非常简单,但是有一点需要额外注意:mark and sweep算法在执行的时候,需要程序暂停!即 STW(stop the world),STW的过程中,CPU不执行用户代码,全部用于垃圾回收,这个过程的影响很大,所以STW也是一些回收机制最大的难题和希望优化的点。所以在执行第三步的这段时间,程序会暂定停止任何工作,卡在那等待回收执行完毕。 mark and sweep 算法 缺点 STW会让程序暂停,使程序出现卡顿(重要问题) 标记需要扫描整个heap 清除数据会产生heap碎片 stw暂停范围 从上图来看,全部的GC时间都是包裹在STW范围之内的,这样貌似程序暂停的时间过长,影响程序的运行性能。所以Go V1.3 做了简单的优化,将STW的步骤提前, 减少STW暂停的时间范围.如下所示 上图主要是将STW的步骤提前了一步,因为在Sweep清除的时候,可以不需要STW停止,因为这些对象已经是不可达对象了,不会出现回收写冲突等问题。 但是无论怎么优化,Go V1.3都面临这个一个重要问题,就是mark-and-sweep 算法会暂停整个程序 。 Go是如何面对并这个问题的呢?接下来G V1.5版本 就用三色并发标记法来优化这个问题. GoV1.5三色标记法 三色标记法无STW的问题 我们加入如果没有STW,那么也就不会再存在性能上的问题,那么接下来我们假设如果三色标记法不加入STW会发生什么事情? 我们还是基于上述的三色并发标记法来说, 他是一定要依赖STW的. 因为如果不暂停程序, 程序的逻辑改变对象引用关系, 这种动作如果在标记阶段做了修改,会影响标记结果的正确性,我们来看看一个场景,如果三色标记法, 标记过程不使用STW将会发生什么事情? 我们把初始状态设置为已经经历了第一轮扫描,目前黑色的有对象1和对象4, 灰色的有对象2和对象7,其他的为白色对象,且对象2是通过指针p指向对象3的,如图所示。 现在如何三色标记过程不启动STW,那么在GC扫描过程中,任意的对象均可能发生读写操作,如图所示,在还没有扫描到对象2的时候,已经标记为黑色的对象4,此时创建指针q,并且指向白色的对象3。 与此同时灰色的对象2将指针p移除,那么白色的对象3实则就是被挂在了已经扫描完成的黑色的对象4下,如图所示。 然后我们正常指向三色标记的算法逻辑,将所有灰色的对象标记为黑色,那么对象2和对象7就被标记成了黑色,如图所示。 那么就执行了三色标记的最后一步,将所有白色对象当做垃圾进行回收,如图所示。 但是最后我们才发现,本来是对象4合法引用的对象3,却被GC给“误杀”回收掉了。 GC误杀条件 可以看出,有两种情况,在三色标记法中,是不希望被发生的。 条件1: 一个白色对象被黑色对象引用**(白色被挂在黑色下)** 条件2: 灰色对象与它之间的可达关系的白色对象遭到破坏**(灰色同时丢了该白色)** 如果当以上两个条件同时满足时,就会出现对象丢失现象!

Linux禁用ipv6

查看是否启用ipv6 首先,可以执行以下命令来检查 IPv6 是否已经启用: 1 ip a 临时禁用ipv6 1 2 3 sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1 sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1 sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=1 检查是否生效 1 ip a 永久禁用ipv6 1 sudo vim /etc/sysctl.conf 在末尾添加 1 2 3 net.ipv6.conf.all.disable_ipv6=1 net.ipv6.conf.default.disable_ipv6=1 net.ipv6.conf.lo.disable_ipv6=1 应用 1 sudo sysctl -p 查看是否生效 1 ip a

Websocket服务端 Golang

服务端1 收到客户端消息马上发回给客户端 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 package main import ( "log" "net/http" "github.com/gorilla/websocket" ) var upgrader websocket.Upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, } func socketHandler(w http.

Golang实现文件断点续传

Golang实现文件断点续传 HTTP 范围请求 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Range_requests https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Range https://juejin.cn/post/7381455296658751551?searchId=202406222022394BE0D5BA1F1DB137CFF5 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status/206 我们首先用golang写一个不具备范围请求的代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 package main import ( "mime" "net/http" "os" "path/filepath" "strconv" "github.
0%