Go语言的网络编程简介

文 | 源小白

共9877字,阅读需25分钟

本文通过 Go 语言写几个简单的通信示例,从 TCP 服务器过渡到 HTTP 开发,从而简单介绍 net 包的运用。

TCP 服务器

首先来看一个 TCP 服务器例子

在对应的文件夹下启动服务器

模拟客户端程序发出请求,这里使用 netcat 工具,也就是 nc 命令。

通过 net 包,我们可以很简单的去写一个 TCP 服务器,代码可读性强。

TCP 客户端

那么我们能不能用 Go 语言来模拟客户端,从而连接前面的服务器呢?答案是肯定的。

运行服务器后,再在所在的文件夹下启动客户端,会看到来自服务器的问候。

TCP 协议模拟 HTTP 请求

我们知道 TCP/IP 协议是传输层协议,主要解决的是数据如何在网络中传输。而 HTTP 是应用层协议,主要解决的是如何包装这些数据。

下面的七层网络协议图也能看到 HTTP 协议是处于 TCP 的上层,也就是说,HTTP 使用 TCP 来传输其报文数据。

七层网络协议图

现在我们写一个基于 TCP 协议的服务器,并能模拟。在这其中,我们需要模拟发送 HTTP 响应头信息,我们可以用 curl -i 命令先来查看一下其他网站的响应头信息。

接下来,我们尝试写出能输出对应格式响应内容的服务器。

启动服务器之后,跳转到 ,就能看到网页内容,并且用开发者工具能看到其请求头。

最简单的 HTTP 服务器

几行代码就能实现一个最简单的 HTTP 服务器。

打开后会发现显示「404 page not found」,这说明 HTTP 已经开始服务了!

ListenAndServe

Go 是通过一个函数 ListenAndServe 来处理这些事情的,这个底层其实这样处理的:初始化一个server 对象,然后调用了 net.Listen("tcp", addr),也就是底层用 TCP 协议搭建了一个服务,然后监控我们设置的端口。

《Build web application with golang》, astaxie

前面我们已经对 TCP 服务器有点熟悉了,而 HTTP 使用 TCP 来传输其报文数据,接下来看看如何用 net/http 包来实现在其上的 HTTP 层。

查文档可以发现 http 包下的 ListenAndServe 函数第一个参数是地址,而第二个是 Handler 类型的参数,我们想要显示内容就要在第二个参数下功夫。

再次查文档,得知 Handler 是一个接口,也就是说只要我们给某一个类型创建 ServeHTTP(ResponseWriter, *Request) 方法,就能符合接口的要求,也就实现了接口。

运行代码后打开能看到输出的字符串。

*http.Request

上面我们实现的小服务器里,我们无论访问 还是 都是一样的页面,这说明我们之前设定的是默认的页面,还没有为特定的路由(route)设置内容。

路由这些信息实际上就存在 ServeHTTP 函数的第二个参数 中, 存放着客户端发送至服务器的请求信息,例如请求链接、请求方法、响应头、消息体等等。

现在我们可以把上面的代码改造一下。

再优雅一点

我们可以用 HTTP 请求多路复用器(HTTP request multiplexer) 来实现分发路由,而 返回的 对象就能实现这样的功能。下面是 的部分源码,能看到通过 就能为每一个路由设置单独的一个 handler 了,简单地说就是不同的内容。

用 来写一个例子。

这样就能为每一个路由设置单独的页面了。

再再优雅一点

还能帮我们简化代码,它默认创建一个 ,也就是默认的 来存 handler 信息,这样就不需要 函数了。这看起来虽然没有什么少写多少代码,但是这是下一个更加优雅方法的转折点。

再再再优雅一点

可以看做 的一种包装。前者的第二个参数变成了一个函数,这样我们就不用多次新建对象,再为对象实现 方法来实现不同的 handler 了。下面是 的部分源码。

用 来重写之前的例子。

HandlerFunc

另外,http 包里面还定义了一个类型 ,该类型默认实现 Handler 接口,我们可以通过 的方式来实现类型强转,使 也实现了 Handler 接口。

结尾

本文从搭建 TCP 服务器一步步到搭建 HTTP 服务器,展示了 Go 语言网络库的强大,我认为 Go 语言是熟悉网络协议的一个很好的工具。自己从熟悉了拥有各种 feature 的 Swift 语言之后再入门到看似平凡无奇的 Go 语言,经历了从为语言的平庸感到惊讶不解到为其遵循规范和良好的工业语言设计而感到惊叹和兴奋的转变。

最后希望本文能为有基础的同学理清思路,也能吸引更多同学来学习这门优秀的语言。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20171224B0NG6O00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券