首先说一下socket , 网络上的两个程序通过一个双向的通信连接实现数据的交换 , 这个连接的一端称为一个socket(百度百科) 。
文章插图
图片来源于网络
其本质就是就是编程接口(API) , 对TCP、UDP的封装 。使用时我们可以指定使用的协议 , 今天主要使用TCP , 目前我们大多数使用的还是TCP , 虽然速度没有UDP快 , 但是更安全 , 如果有能力的同学 , 可以使用UDP同时在上层能够检测到传输数据是否有丢失 , 这个不是很简单做到的 。今天就以TCP为例 , 说一下Go语言实现一个简单的sever 。
go语言的网络编程主要是net包 , 我们使用:
func Listen(network, address string) (Listener, error)这个接口来监听我们的端口 , 并且指定协议 。这里会返回一个Listener对象 , 就是一个接口 , 其中实现了三个方法:Accept(),Close(),Addr() 。其中Accept返回一个Conn对象 , 这个就是我们最终需要的 , 这里面包括了请求数据 。看一下简单的代码实现:
func main() { addr := "0.0.0.0:8080" listener, err := net.Listen("tcp", addr) if err != nil { panic(err) } defer listener.Close() for { conn, err := listener.Accept() if err != nil { break } go handleReq(conn) // 启用一个协程处理请求 }}func handleReq(conn net.Conn) { // todo}上面的代码实现了对本地8080端口的监听 , 每当有一个请求过来时 , 我们单独一个协程来处理这个请求 , 这样不至于一个请求阻塞在这里 。
接下来我们就是对请求的处理 , 在看handleReq方法的具体实现:
func handleReq(conn net.Conn) { defer conn.Close() data := make([]byte, 1024) _, err := conn.Read(data) if err != nil { panic(err) } // 获取收到的数据后 , 存到 data 中 , 根据实际需求做处理 。fmt.Println(string(data)) // 处理之后 , 我们将需要的信息返回给客户端 。res := "收到了你的请求" _, err = conn.Write([]byte(res)) if err != nil { panic(err) }}在方法中我们接收一个conn , 就是与客户端的连接 , 我们可以想象成sever与client的连接有一个管道 , 我们在管道中传输数据 , 而这个conn对象就是这个管道 , 我们先从这个管道中读取客户端发来的数据 , 接着根据业务需求来正确的处理 , 例如这个请求可能是一个用户登录的请求 , 我们发来的数据就是用户输入的用户名和密码等信息 , 在我们知道这是一个用户登录的请求时 , 就知道接下来该怎么做了 。
【go语言网络编程之socket sever的实现】那么我们如何知道这个是用户登录的请求呢?这时我们就可以通过一个规定 , 传过来的数据可以是一个strct , 其中一个字段是Type , 我们可以根据这个Type来知道这到底是一个什么请求 , 然后在对请求数据做处理 。比如 , 查询一下这个用户名是否存在 , 密码是否正确等 , 然后将对应信息返回即可 。这时 , 我们通过这根管道已经发送完数据 , 将管道关闭就可以了:
defer conn.Close()建议大家多用defer , go语言提供这个很大程度的方便了写代码 。
至此我们sever的简单实例就完成了 , 我们回头再看 , 我们先是使用for循环 , 不断的接收客户端的请求 , 每当有一个请求 , 我们创建一个协程来处理 , 这样我们就可以不断的接收请求 , 只需要将于客户端连接的管道给一个协程就好了 。
这是最简单的sever的实现 , 但是我们在项目中 , 其实可以对其封装 , 多利用go的并发特性 , 使用channel来通信 , 例如 , 我们可以将sever封装成一个对象 , sever监听开始时 , 创建一个协程来等待客户端的接口 , 同时创建一个协程读取请求数据 , 还可以创建一个协程来对每个请求数据单独处理等 , 多个协程工作效率会更好的 , 对并发很高时还是很有效的 。
文章插图
推荐阅读
- 茶道 人道 天道
- HTML和HTML5之间有什么区别?
- 网站seo优化之图片优化
- php加速器之opcache
- 韩国茶道文化之高丽饮茶史
- 荔枝干的壳泡水喝的功效 荔枝泡盐水是剥开壳之后泡还是连壳一起泡
- 如梦之梦武汉站什么时候开票
- 风水学入门之家居旺财布局
- 风水入门之如何看房子风水好坏
- 茶花之插