meowrain

MeowRain

Life is Simple

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垃圾回收机制

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.

Go Net/Http库

Go net/http库 Get()方法 函数原型 1 func Get(url string) (resp *Response, err error) 使用示例: 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 package main import ( "fmt" "io" "log" "net/http" ) func main() { response, err := http.Get("http://httpbin.org/get") if err != nil { log.Fatal(err) } fmt.

Linux系统编程 标准IO 打开并读写文件

https://cplusplus.com/reference/cstdio/fopen/ https://cplusplus.com/reference/cstdio/fgetc/?kw=fgetc https://cplusplus.com/reference/cstdio/fputc/?kw=fputc https://cplusplus.com/reference/cstdio/fgets/?kw=fgets https://cplusplus.com/reference/cstdio/fputs/?kw=fputs https://man7.org/linux/man-pages/man3/getline.3.html https://cplusplus.com/reference/cstdio/feof/?kw=feof https://cplusplus.com/reference/cstdio/fclose/?kw=fclose https://cplusplus.com/reference/cstdio/fread/?kw=fread https://cplusplus.com/reference/cstdio/fwrite/?kw=fwrite https://cplusplus.com/reference/cstdio/fseek/?kw=fseek https://cplusplus.com/reference/cstdio/rewind/kw=rewind https://cplusplus.com/reference/cstdio/ftell/?kw=ftell fopen: 函数原型:FILE *fopen(const char *filename, const char *mode); 功能:打开一个文件,并返回一个指向该文件的文件指针(FILE 类型)。这个文件指针用于后续的文件读写操作。 参数: filename:指向一个以空字符结尾的字符串,该字符串指定要打开的文件名,可以包含路径信息。 mode:指向一个以空字符结尾的字符串,指定文件的打开模式。常见的模式包括: "r":以只读方式打开文件(文件必须存在)。 "w":以写入方式打开文件,如果文件不存在则创建,如果文件已存在则清空文件内容。 "a":以追加方式打开文件,如果文件不存在则创建,写入的数据追加到文件末尾。 "r+":以读写方式打开文件(文件必须存在)。 "w+":以读写方式打开文件,如果文件不存在则创建,如果文件已存在则清空文件内容。 "a+":以读取和追加方式打开文件,如果文件不存在则创建,读取从文件开始,写入追加到文件末尾。 还可以在上述模式后添加 "b" 来以二进制模式打开文件,例如 "rb"、"wb" 等。 返回值:成功时返回一个有效的文件指针,如果文件无法打开,则返回 NULL。 在使用 fopen 打开文件后,通常需要检查返回的文件指针是否为 NULL 来确保文件成功打开。文件使用完毕后,应使用 fclose 函数关闭文件,释放资源。例如: 1 2 3 4 5 6 7 8 9 10 11 12 13 FILE *fp; char *filename = "example.txt"; char *mode = "r"; fp = fopen(filename, mode); if (fp == NULL) { printf("无法打开文件\n"); return 1; } // 文件操作代码.
0%