从6.824的kv.go理解tcp协议

本文是在学习6.824课程时,对Lec 2的kv.go产生的困惑的解释和总结。
kv.go
首先对kv.go的情况进行解释。这里只会取一些重点片段进行解释,需要了解完整代码细节的,读者可自行选择文章最后的参考条目进行详细了解。
主逻辑
1 | func main() { |
主逻辑非常简单,启动一个kv存储的rpc服务,然后运行简单的读写功能测试。
server()
1 | func server() { |
启动服务,监听1234端口,并开始接受客户端的连接
client
1 | func get(key string) string { |
客户端方法总体逻辑是一致,首先进行tcp连接的建立,然后进行rpc方法调用,最后关闭连接
解析过程
如果你运行该程序,会发现打印如下:
1 | $ go run kv.go |
为什么程序最后会退出,而不是因为server在监听阻塞住。我自己的解释是:首先是因为server()中的无限接收请求的循环是运行在goroutine当中,所以之后的客户端请求可以并发的运行;其次因为主线程没有其他方法的阻塞,所以会在所有逻辑结束后退出,也意味该进程退出了,这样其中的所有线程都会结束,包括其中创建的goroutine。
如果读者有更好的解释欢迎留言讨论。
在该程序的主逻辑中,实际发生了两次tcp连接,我们知道一次tcp协议的运行过程有三个阶段:连接创建、数据传送和连接终止。server()下开启的rpc服务监听着1234端口,而get和put()中的connect()则完成一次tcp连接创建的三次握手,如图下
此时通过netstat命令查看会出现有两个连接以及一个监听
当数据传送完毕,get和put()调用Close()方法进入连接终止阶段(四次握手)后,客户端状态则会进入TIME_WAIT状态
等待2MSL后,客户端Close。
如果希望对TCP的设计想要更深入了解,可以参考
REFERENCE
[1] 6.824 kv.go
[2] 维基百科
- Title: 从6.824的kv.go理解tcp协议
- Author: 𝖋𝖊𝖓𝖌𝖟𝖜
- Created at : 2021-04-11 14:08:55
- Updated at : 2025-02-22 23:37:10
- Link: https://zhiwei-feng.github.io/2021/04/11/socket-analysis-for-6-824-kv-go/
- License: This work is licensed under CC BY-NC-SA 4.0.