从gin的启动开始看socket是如何在服务器中创建的:
gin -> net/http -> net -> internal/syscall -> syscall -> runtime
通过上面的调用流程,可以看出,http是对net的封装,方便开发者调用,实际创建Socket的还是net库,底层已经是到了go的syscall和runtime库了。
最终调用的还是操作系统提供的socket接口。这就是socket创建的流程。
具体流程涉及的文件以及代码:
router.go
1 2 | r := gin.New() r.Run(address) // host:port |
github.com\gin-gonic\gin@v1.7.7\gin.go
1 | err = http.ListenAndServe(address, engine) |
Go\src\net\http\server.go
1 2 3 4 5 6 | // Go net/http包 return server.ListenAndServe() ln, err := net.Listen( "tcp" , addr) // http也是对net的封装 if err != nil { return err } |
Go\src\net\dial.go
1 2 | return lc.Listen(context.Background(), network, address) l, err = sl.listenTCP(ctx, la) |
Go\src\net\tcpsock_posix.go
1 | fd, err := internetSocket(ctx, sl.network, laddr, nil, syscall.SOCK_STREAM, 0, "listen" , sl.ListenConfig.Control) |
Go\src\net\ipsock_posix.go
1 | return socket(ctx, net, family, sotype, proto, ipv6only, laddr, raddr, ctrlFn) // 出现socket函数了 |
Go\src\net\sock_posix.go
1 2 3 4 | // socket returns a network file descriptor that is ready for // asynchronous I/O using the network poller. s, err := sysSocket(family, sotype, proto) |
Go\src\net\sock_windows.go
1 | s, err := wsaSocketFunc(int32(family), int32(sotype), int32(proto),nil, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT) |
Go\src\net\hook_windows.go
1 | wsaSocketFunc func(int32, int32, int32, *syscall.WSAProtocolInfo, uint32, uint32) (syscall.Handle, error) = windows.WSASocket // windows.WSASocket就是返回的socket |
Go\src\internal\syscall\windows\zsyscall_windows.go
1 2 3 4 5 6 7 8 9 | // 可以看到文件已经跳转到internal文件夹下的系统相关调用目录 func WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, group uint32, flags uint32) (handle Handle, err error) { r0, _, e1 := syscall.Syscall6(procWSASocketW.Addr(), 6, uintptr(af), uintptr(typ), uintptr(protocol), uintptr( unsafe .Pointer(protoInfo)), uintptr( group ), uintptr(flags)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) } return } |
=== r0 start ===
Go\src\syscall\dll_windows.go
1 2 3 4 | // 可以看到文件已经跳转到syscall系统调用目录,dll_windows名称也可看出该文件底层调用的是windos系统提供的接口。 // Implemented in ../runtime/syscall_windows.go. // 注释中是说继承于../runtime/syscall_windows.go文件中的Syscall6,这个写法比较特殊,是go1.14刚出的,go:linkname,有兴趣的可以继续深入这个写法,这里不做赘述。 func Syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) |
Go\src\runtime\syscall_windows.go
1 2 3 4 5 6 7 8 9 10 11 12 13 | //go:linkname syscall_Syscall6 syscall.Syscall6 //go:nosplit //go:cgo_unsafe_args func syscall_Syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { lockOSThread() defer unlockOSThread() c := &getg().m.syscall c.fn = fn c.n = nargs c.args = uintptr(noescape( unsafe .Pointer(&a1))) cgocall(asmstdcallAddr, unsafe .Pointer(c)) return c.r1, c.r2, c.err } |
=== r0 end ===
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具