首先,socket底层不care用户层是多线程还是单线程

其次,golang标准库中的TCPConn不是简单调用底层socket的读写系统调用。举个例子:“应用程序多个goroutine在一个socket上进行读操作,当socket上没有数据可读时,go runtime需要将读操作的多个goroutine阻塞,并挂到与此socket相关的一个等待列表上。当socket有可读数据时,go runtime会将等待列表上的goroutine置为可运行状态,并等待调度器调度。“ Read或者Write时加锁的目的就是做以上一系列操作。

最后,针对问题 “那心跳包要怎么实现呢,现在的很多程序,心跳包都是一个单独的goroutine在发,只能在写业务逻辑时,心跳包与实际业务报文顺序发送?”。golang的TCPConn的Write方法是有锁的,所以即使是多个goroutine同时写同一个socket,也必然有先后顺序,不可能出现心跳包写一半,业务包写一半。