"千篇一律,高手寂寞。几十不惑,全都白扯"

上篇介绍了golang这门新的语言的一些语法。那么我们能用golang简单地写些什么代码出来呢?

一、猜数字

这个游戏的逻辑很简单。系统随机给你生成一个数,然后读取你猜的数字,再根据你猜的数字 跟系统生成的数字比较。告诉你结果这样。

(1)随机生成一个数

随机生成一个区间在1~100之间的数。

import math/rand
import time

package mainimport ("fmt""math/rand""time"
)func main() {maxNum := 100rand.Seed(time.Now().UnixNano())secretNum := rand.Intn(maxNum)fmt.Println("The secert number is:", secretNum)
}

用C\C++写过类似程序的朋友们,都会知道使用rand 的时候,如果不设置rand种子,那么生成的随机数是固定的。因此,我们import time,用time中的时间戳,设置rand的种子。

(2)获取用户输入的值

生成要猜的数字是第一步,那么接下来要进行的就是获取用户输入的值。在go中有两个解法

fmt.Scanf;

这个fmt.Scanf的使用和C中的scanf相差无几。也是最简单的获取值的方式。

bufio\os;

bufio:
Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer object, creating another object (Reader or Writer) that also implements the interface but provides buffering and some help for textual I/O.

bufio包实现IO缓冲。它包装了一个可读或者可写的io对象,并创建一个另一个实现接口的对象,为文本文件提供帮助和缓冲

如果有一定的linux系统的知识,对"linux下一切皆文件"这句话不陌生。在linux系统看来,我们的显示器是文件。程序获取用户的数据,是从键盘输入回显到显示器,再从显示器中拿到的。

os:
Package os provides a platform-independent interface to operating system functionality. The design is Unix-like, although the error handling is Go-like; failing calls return values of type error rather than error numbers. Often, more information is available within the error. For example, if a call that takes a file name fails, such as Open or Stat, the error will include the failing file name when printed and will be of type *PathError, which may be unpacked for more information.

简单来说,这个包是提供给用户,独立地操作系统功能的接口。

将从显示器的文件数据,创建另一个对象(reader)管理

reader提供了ReadString的API接口。我试试看

我们通过readString函数,把reader中的值给input。但是这个值不是很干净! 因为有"\r\n"。这个的存在是因为我们敲击了回车!为此,我们需要将input末尾的后缀给干掉!

我们使用strings包里面TrimSuffix的这个函数,顾名思义,是一个过滤后缀的函数。

(3)游戏逻辑判断

打印到显示器上的字符,到底是数字还是字符串?答案是字符串!我们得到的input的值,其实是一段自子串。因此,我们用到如TrimSuffix函数 是针对字符串类型的,而字符串的大小比较 和 整数的大小比较是不一样的!

strconv;

package strconv implements conversions to and from string representations of basic data types
包strconv实现基本数据类型的字符串表示形式之间的相互转换。

后面判断的逻辑也比较简单。也就不多言了。

(4)测试

package mainimport ("fmt""math/rand""time"//系统接口"bufio""os"//strings操作"strconv""strings"
)func main() {maxNum := 100rand.Seed(time.Now().UnixNano())secretNum := rand.Intn(maxNum)fmt.Println("The secert number is:", secretNum)for {fmt.Println("Please Enter your guess~ ")// input := 0// fmt.Scanf("%d", &input)// fmt.Println(input)reader := bufio.NewReader(os.Stdin)//拆解input, err := reader.ReadString('\n')if err != nil {fmt.Println("An input Error,Please reinput again", err)return}//fmt.Printf("Befor:%#v\n", input)input = strings.TrimSuffix(input, "\n")input = strings.TrimSuffix(input, "\r")//fmt.Printf("After:%#v\n", input)guess, err := strconv.Atoi(input)if err != nil {fmt.Println("Invalid input,Please Enter your guess again~", err)return}fmt.Println("Your guess is", guess)//逻辑判断if guess > secretNum {fmt.Println("More bigger")} else if guess < secretNum {fmt.Println("Less smaller")} else {fmt.Println("You are preety good,and correct: ", secretNum)break}}
}

二、在线词典

我们准备通过http,得到一个英文单词的翻译。

大概是这样的格式。那么制作这个肯定需要一定的网络基础。

(1)处理请求

main;

我们通过命令行,上传我们的请求。这里又要使用到我们的"老朋友" ——os package

JSON;

JSON是一种轻量级的数据交换格式。它采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

//请求报头
type DictRequest struct{TransType string `json:"trans_type"`Source string `json:"source"`UserID string `json:"user_id"`
}

有了请求报头,接下来就需要应对对端返回的json数据应该如何解析。对于js/python这些脚本语言,有字典、map的概念,可以直接从json里面取值。但是对golang是不行的。需要golang创建一个结构体作为解析时的填充对象。

网上有这样结构体代码的生成工具,要我们自己写肯定很麻烦。

type DictResponse struct {Rc   int `json:"rc"`Wiki struct {KnownInLaguages int `json:"known_in_laguages"`Description     struct {Source string      `json:"source"`Target interface{} `json:"target"`} `json:"description"`ID   string `json:"id"`Item struct {Source string `json:"source"`Target string `json:"target"`} `json:"item"`ImageURL  string `json:"image_url"`IsSubject string `json:"is_subject"`Sitelink  string `json:"sitelink"`} `json:"wiki"`Dictionary struct {Prons struct {EnUs string `json:"en-us"`En   string `json:"en"`} `json:"prons"`Explanations []string      `json:"explanations"`Synonym      []string      `json:"synonym"`Antonym      []string      `json:"antonym"`WqxExample   [][]string    `json:"wqx_example"`Entry        string        `json:"entry"`Type         string        `json:"type"`Related      []interface{} `json:"related"`Source       string        `json:"source"`} `json:"dictionary"`
}

这样我们就得到了JSON结构体。解析http返回的报头。

net/http;

Package http provides HTTP client and server implementations.
包http提供了HTTP客户端和服务器实现。

client是http中的一个对象

Marshal;

bytes;

Package bytes implements functions for the manipulation of byte slices. It is analogous to the facilities of the strings package.

实现了操作子串切片的操作。类似字符串包strings的功能

(2)处理响应

发送一个http请求,并返回一个http响应。

而此时我们响应数据全在resp中。我们需要的是响应数据中的正文部分。

ioutil;

Package util contains utility code for use by volume plugins.

这个包提供一些好用的工具

但是,我们此时拿到的正文数据,是JSON格式的。我们为此需要将次填入我们为JSON事先创建好的结构体中。这个过程叫做,反序列化。

我们也就拿到返回的数据内容了。

(3)数据解析

我们来看看效果吧~

三、SOCKET5代理

(1)代理服务器简介

代理服务器(Proxy Server)的功能是代理网络用户去取得网络信息。形象地说,它是网络信息的中转站,是个人网络和Internet服务商之间的中间代理机构,负责转发合法的网络信息,对转发进行控制和登记。

取自这里

SOCKS5 是一个代理协议,它在使用TCP/IP通讯的前端机器和服务器机器之间扮演一个中介角色,使得内部网中的前端机器变得能够访问Internet网中的服务器,或者使通讯更加安全。SOCKS5 服务器通过将前端发来的请求转发给真正的目标服务器, 模拟了一个前端的行为。在这里,前端和SOCKS5之间也是通过TCP/IP协议进行通讯,前端将原本要发送给真正服务器的请求发送给SOCKS5服务器,然后SOCKS5服务器将请求转发给真正的服务器。
SOCKS5虽然是代理服务协议,但是不用作"翻墙",它的协议是明文传输。

取自这里

(2)SOCKS5原理

(3)建立TCP

package mainimport ("log""net"
)func main() {server, err := net.Listen("tcp", "127.0.0.1:8801")if err != nil {log.Fatal(err)}for {client, err := server.Accept()if err != nil {log.Printf("Accept faild:%v", err)//没有链接到来持续等待即可continue}//连接到来go proceess(client)}
}func proceess(conn net.Conn) {}

goroutinue 可以类比一个进程里的子进程,但是开销小很多。

Process;

func proceess(conn net.Conn) {defer conn.Close()reader := bufio.NewReader(conn)for {b, err := reader.ReadByte()if err != nil {break}_, err = conn.Write([]byte{b})if err != nil {break}}
}

defer这一行的含义,就是在函数结束时,释放掉资源。防止资源泄漏

接下来我们使用的bufio。我们在猜数字的时候用过。它为可读或可写的对象提供一个缓冲区。这里的IO输出是针对网络套接字,但是IO的速度是很慢的。因此,我们把网络数据 转换为bufio的形式,减少底层系统调用,同时,bufio也会提供一定的工具帮我们对数据进行获取。

这里conn底层回去调用Write。conn保存了系统为这个连接打开的fd。

(4)认证阶段

代理服务器不仅仅是获取数据即可。否则我们刚刚完成一个TCP连接即可。

认证时,浏览器会发三个字段给代理服务器:version、methods、methods编码

version;

method;

它返回复制的字节数,如果读取的字节数较少,则返回一个错误。

这样我们也就获取了version与method;此时,代理服务器需要向 浏览器返回两个字段,version\method;

(5)请求阶段

在这个阶段,我们就需要拿到浏览器url里面访问的IP+PORT,定位服务器。此时我们增加了一个connect函数帮我们完成这个功能

atyp地址类别;

如果是IPV4,我们逐个将这刚好4字节打印成IP地址的格式。

如果是host,我们则需要重新计算大小,转换成字符串并保存。

IPV6这里算了。用得少。

端口port;

我们日常生活中的有大端机,小端机。所谓大小端机最大的差别,就在于存储字符的字节序不同。为了屏蔽掉这个差异,网络中统一发送的字节序为大端字节序。如果是小端机接收,那么你就需要进行转换,如果是大端,那就什么都可以不做。

(6)Relay阶段

此时两端主机正式开始建立连接了。

但是有个问题是,一旦执行到这里,connect函数就会结束。那么两个端的连接也就会被关闭。因此,什么时候应该是将两端连接关闭呢? 一旦其中一方出现copy错误时~

context;

Package context defines the Context type, which carries deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.

包上下文定义了上下文类型,它携带截止日期、取消信号和其他跨API边界和进程间的请求范围的值。

当调用cancel()的时候, 处于等待的ctx.Done()会立即返回。

以上也就简简单单用golang做了一些小的代码。

感谢你的阅读,

祝你好运,向阳而生~

Golang之实战篇相关推荐

  1. Golang流媒体实战之五:lal推流服务源码阅读

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos <Golang流媒体实战>系列的链接 体验 ...

  2. Golang流媒体实战之一:体验开源项目lal

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于<Golang流媒体实战> 因为工作需 ...

  3. Golang流媒体实战之六:lal拉流服务源码阅读

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos <Golang流媒体实战>系列的链接 体验 ...

  4. linux下文件字符集转化实战篇

    linux下文件字符集转化实战篇 ------------------------------------------ 为什么转换编码,起因:分析应用程序日志,文件编码格式gb2312(含中文字符), ...

  5. 跟安全技术大师学习黑客攻防技术 ——《黑客攻防技术宝典:web实战篇》

    跟安全技术大师学习黑客攻防技术 --<黑客攻防技术宝典: web 实战篇> 随着网络技术的快速发展以及网络带宽的不断扩张, Web 应用程序几乎无处不在,渗透到社会的经济.文化.娱乐等各个 ...

  6. 人工智能之算法知识与实战篇

    http://blog.itpub.net/31549715/viewspace-2200127/ 写在前头 1.课程的选择: 选择一门完整的算法课程,并以此课程为主,系统性学习:公众号或者其他材料都 ...

  7. 开发人员MySQL调优-实战篇2-让SQL使用索引详解

    2019独角兽企业重金招聘Python工程师标准>>> 建议先看看开发人员MySQL调优-实战篇0 让执行的SQL使用索引 虽然DBA给我们建了很多索引,但没有经验的开发人员往往只看 ...

  8. Systemd 入门教程:实战篇

    Systemd 入门教程:实战篇 原文出处: 阮一峰(@ruanyf)   http://blog.jobbole.com/98671/?utm_source=blog.jobbole.com& ...

  9. 使用Cloudera Manager搭建zookeeper集群及HDFS HA实战篇

    使用Cloudera Manager搭建zookeeper集群及HDFS HA实战篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.使用Cloudera Manager搭建zo ...

最新文章

  1. 安卓读取mysql数据库文件路径_Android开发实现读取assets目录下db文件的方法示例...
  2. php protected 属性,PHP实现在对象之外访问其私有属性private及保护属性protected的方法...
  3. 素数与量子物理的结合能带来解决黎曼猜想的新可能吗?
  4. Java虚拟机常量池和本地变量表、自己定义的数值自动装入常量池
  5. 税务审计SAP需要用表
  6. linux考试基础知识测验
  7. 强悍的 Ubuntu —— 强悍的任意进制转换命令行工具 bc
  8. 学习Hadoop需要哪些预备知识?Java是否必须会?
  9. Linux中把程序添加到系统服务中
  10. 中国多接收器电感耦合等离子体质谱仪市场行业产销需求与投资预测分析报告2022-2028年
  11. reviewboard--ubuntu安装reviewboard
  12. oracle的多个exclude,记录一下expdp exclude的用法
  13. 【原创】基于.NET的轻量级高性能 ORM - TZM.XFramework
  14. 【python学习】如何将字典添加到字典
  15. Sonatype Nexus Repository Manager
  16. 如何在debian上安装google pingyin
  17. 世界最清楚tensorflow入门教程
  18. [Alpha] Scrum Meeting 8 - TEAM LESS ERROR
  19. 电商干货!1000万烧出来的高点击率钻展创意图十大原则(营销人性)
  20. 【2020.11.4 洛谷团队赛 普及组】T1 U138644 小Biu的礼物

热门文章

  1. 电化学微量元素分析仪的执行标准
  2. 【测试表征】电化学循环伏安法QA
  3. 玩转 ArrayFire:07 数组和矩阵操作
  4. 邀请函二维码怎么制作?怎么把邀请函做成二维码?
  5. 增广拉格朗日乘子法(Augmented Lagrange Method)
  6. 单片机学习笔记————51单片机实现带数码管显示的象棋比赛专用计时器
  7. 集合框架——Set集合的使用与数据结构详解
  8. 联想T470P新增固态硬盘
  9. 思科AP修改AP位置描述通过WLC命令方式
  10. java实现贴吧源码_基于jsp的贴吧系统-JavaEE实现贴吧系统 - java项目源码