加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959

net

import "net"

net包提供了可移植的网络I/O接口,包括TCP/IP、UDP、域名解析和Unix域socket。

虽然本包提供了对网络原语的访问,大部分使用者只需要Dial、Listen和Accept函数提供的基本接口;以及相关的Conn和Listener接口。crypto/tls包提供了相同的接口和类似的Dial和Listen函数。

Listen函数创建的服务端:

ln, err := net.Listen("tcp", ":8080")
if err != nil {
// handle error
}
for {
conn, err := ln.Accept()
if err != nil {
// handle error
continue
}
go handleConnection(conn)
}

Dial函数和服务端建立连接:

conn, err := net.Dial("tcp", "google.com:80")
if err != nil {
// handle error
}
fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
status, err := bufio.NewReader(conn).ReadString('\n')
// ...

TCPConn

TCPConn代表一个TCP网络连接,实现了Conn接口。

Conn接口

Conn接口代表通用的面向流的网络连接。多个线程可能会同时调用同一个Conn的方法。

type Conn interface {
// Read从连接中读取数据
// Read方法可能会在超过某个固定时间限制后超时返回错误,该错误的Timeout()方法返回真
Read(b []byte) (n int, err error)
// Write从连接中写入数据
// Write方法可能会在超过某个固定时间限制后超时返回错误,该错误的Timeout()方法返回真
Write(b []byte) (n int, err error)
// Close方法关闭该连接
// 并会导致任何阻塞中的Read或Write方法不再阻塞并返回错误
Close() error
// 返回本地网络地址
LocalAddr() Addr
// 返回远端网络地址
RemoteAddr() Addr
// 设定该连接的读写deadline,等价于同时调用SetReadDeadline和SetWriteDeadline
// deadline是一个绝对时间,超过该时间后I/O操作就会直接因超时失败返回而不会阻塞
// deadline对之后的所有I/O操作都起效,而不仅仅是下一次的读或写操作
// 参数t为零值表示不设置期限
SetDeadline(t time.Time) error
// 设定该连接的读操作deadline,参数t为零值表示不设置期限
SetReadDeadline(t time.Time) error
// 设定该连接的写操作deadline,参数t为零值表示不设置期限
// 即使写入超时,返回值n也可能>0,说明成功写入了部分数据
SetWriteDeadline(t time.Time) error
}

栗子一(tcp)

tcp服务端

package main

import (
"fmt"
"net"
) func process(conn net.Conn) {
defer conn.Close()
for {
buf := make([]byte, )
n, err := conn.Read(buf)
if err != nil {
fmt.Println("read err:", err)
return
}
fmt.Println("read:", string(buf[:n]))
}
} func main() {
fmt.Println("server start...")
listen, err := net.Listen("tcp", "0.0.0.0:8000")
if err != nil {
fmt.Println("listen failed, err:", err)
return
}
for {
conn, err := listen.Accept()
if err != nil {
fmt.Println("accept failed, err:", err)
continue
}
go process(conn)
}
}

tcp客户端

package main

import (
"bufio"
"fmt"
"net"
"os"
"strings"
) func main() {
conn, err := net.Dial("tcp", "localhost:8000")
if err != nil {
fmt.Println("err dialing:", err.Error())
return
}
defer conn.Close()
inputReader := bufio.NewReader(os.Stdin)
for {
input, _ := inputReader.ReadString('\n')
trimedInput := strings.Trim(input, "\r\n")
if trimedInput == "Q" {
return
}
_, err := conn.Write([]byte(trimedInput))
if err != nil {
fmt.Println("err conn.write:", err)
return
}
}
}

栗子二(http)

封装一个http连接,请求百度

package main

import (
"fmt"
"io"
"net"
) func main() {
conn, err := net.Dial("tcp", "www.baidu.com:80")
if err != nil {
fmt.Println("err dialing:", err.Error())
return
}
defer conn.Close() msg := "GET / HTTP/1.1\r\n"
msg += "Host: www.baidu.com\r\n"
msg += "Connection: close\r\n"
// msg += "Connection: keep-alive\r\n"
msg += "\r\n\r\n" _, err = io.WriteString(conn, msg)
if err != nil {
fmt.Println("io write string failed, err:", err)
return
}
buf := make([]byte, )
for {
count, err := conn.Read(buf)
if err != nil {
break
}
fmt.Println(string(buf[:count]))
}
}

net/http

import "net/http"

http包提供了HTTP客户端和服务端的实现。

Get、Head、Post和PostForm函数发出HTTP/ HTTPS请求。

resp, err := http.Get("http://example.com/")
...
resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
...
resp, err := http.PostForm("http://example.com/form",
url.Values{"key": {"Value"}, "id": {""}})

程序在使用完回复后必须关闭回复的主体。

resp, err := http.Get("http://example.com/")
if err != nil {
// handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
// ...

要管理HTTP客户端的头域、重定向策略和其他设置,创建一个Client:

client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
resp, err := client.Get("http://example.com")
// ...
req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
// ...

要管理代理、TLS配置、keep-alive、压缩和其他设置,创建一个Transport:

tr := &http.Transport{
TLSClientConfig: &tls.Config{RootCAs: pool},
DisableCompression: true,
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://example.com")

Client和Transport类型都可以安全的被多个go程同时使用。出于效率考虑,应该一次建立、尽量重用。

ListenAndServe使用指定的监听地址和处理器启动一个HTTP服务端。处理器参数通常是nil,这表示采用包变量DefaultServeMux作为处理器。Handle和HandleFunc函数可以向DefaultServeMux添加处理器。

http.Handle("/foo", fooHandler)
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})
log.Fatal(http.ListenAndServe(":8080", nil))

要管理服务端的行为,可以创建一个自定义的Server:

s := &http.Server{
Addr: ":8080",
Handler: myHandler,
ReadTimeout: * time.Second,
WriteTimeout: * time.Second,
MaxHeaderBytes: << ,
}
log.Fatal(s.ListenAndServe())

栗子server

import (
"fmt"
"net/http"
) func Hello(w http.ResponseWriter, r *http.Request) {
fmt.Println("Hello World.")
fmt.Fprintf(w, "Hello World.\n")
} func main() {
http.HandleFunc("/", Hello)
err := http.ListenAndServe("0.0.0.0:6000", nil)
if err != nil {
fmt.Println("http listen failed.")
}
}

栗子client

import (
"fmt"
"io/ioutil"
"net/http"
) func main() {
res, err := http.Get("http://www.baidu.com")
if err != nil {
fmt.Println("Get error:", err)
return
} data, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println("Get data error:", err)
return
} fmt.Println(string(data))
}

栗子head

import (
"fmt"
"net/http"
"time"
) var url = []string{
"http://www.baidu.com",
"http://www.google.com",
"http://pan.263.net",
} func main() {
for _, v := range url {
http.DefaultClient.Timeout = time.Second *
resp, err := http.Head(v)
if err != nil {
fmt.Printf("head %s failed, err: %v\n", v, err)
continue
}
fmt.Printf("head %s succ, status: %v\n", v, resp.Status)
}
}

栗子(form)

import (
"fmt"
"io"
"log"
"net/http"
) const form = `
<html>
<body>
<form action="#" method="post" name="bar">
<input type="text" name="in"/>
<input type="text" name="in"/>
<input type="submit" value="Submit"/>
</form>
</body>
</html>
` func SimpleServer(w http.ResponseWriter, request *http.Request) {
io.WriteString(w, "Hello World.")
} func FormServer(w http.ResponseWriter, request *http.Request) {
w.Header().Set("Content-Type", "text/html")
switch request.Method {
case "GET":
io.WriteString(w, form)
case "POST":
request.ParseForm()
io.WriteString(w, request.Form["in"][])
io.WriteString(w, "\n")
io.WriteString(w, request.FormValue("in"))
}
} func logPanics(handle http.HandlerFunc) http.HandlerFunc {
return func(writer http.ResponseWriter, request *http.Request) {
defer func() {
if x := recover(); x != nil {
log.Printf("[%v] caught panic: %v", request.RemoteAddr, x)
}
}()
handle(writer, request)
}
} func main() {
http.HandleFunc("/test1", SimpleServer)
http.HandleFunc("/test2", logPanics(FormServer))
err := http.ListenAndServe("0.0.0.0:6000", nil)
if err != nil {
fmt.Println("http listen failed.")
}
}

栗子(template)

package main

import (
"fmt"
"html/template"
"net/http"
) type Person struct {
Title string
Name string
Age int
} func SimpleServer(w http.ResponseWriter, request *http.Request) {
indexFailPath := "./index.html"
t, err := template.ParseFiles(indexFailPath)
if err != nil {
fmt.Println("parse file err:", err)
return
}
p := Person{Name: "Nick", Age: , Title: "Good."}
if err = t.Execute(w, p); err != nil {
fmt.Println("There was an error:", err.Error())
return
}
} func main() {
http.HandleFunc("/test1", SimpleServer)
err := http.ListenAndServe("0.0.0.0:9000", nil)
if err != nil {
fmt.Println("http listen failed.")
}
}
<html>
<head>
<title>
{{.Title}}
</title>
</head>
<body>
<p>{{.Name}}</p>
{{if gt .Age }}
<p>MAN: {{.Name}}</p>
{{else}}
<p>Kid: {{.Name}}</p>
{{end}}
</body>
</html>

更多用法

  • not 非
{{if not .condition}} 
{{end}}

  • and 与
{{if and .condition1 .condition2}} 
{{end}}

  • or 或
{{if or .condition1 .condition2}} 
{{end}}

  • eq 等于
{{if eq .var1 .var2}} 
{{end}}

  • ne 不等于
{{if ne .var1 .var2}} 
{{end}}

  • lt 小于 (less than)
{{if lt .var1 .var2}} 
{{end}}

  • le 小于等于
{{if le .var1 .var2}} 
{{end}}

  • gt 大于
{{if gt .var1 .var2}} 
{{end}}

  • ge 大于等于
{{if ge .var1 .var2}} 
{{end}}
  • range 循环 {{range.}} {{end }}

Appendix

大端字节序的实现

    data, err := json.Marshal("hello world")
if err != nil {
return
} var buf []byte
packLen := uint32(len(data))
fmt.Println("packlen:", packLen) // 前4个字节表示data大小
binary.BigEndian.PutUint32(buf[:], packLen) n, err := conn.Write(buf[:])
if err != nil || n != {
fmt.Println("write data failed")
return
} _, err = conn.Write([]byte(data))
if err != nil {
return
}

Http  状态码

const (
StatusContinue =
StatusSwitchingProtocols =
StatusOK =
StatusCreated =
StatusAccepted =
StatusNonAuthoritativeInfo =
StatusNoContent =
StatusResetContent =
StatusPartialContent =
StatusMultipleChoices =
StatusMovedPermanently =
StatusFound =
StatusSeeOther =
StatusNotModified =
StatusUseProxy =
StatusTemporaryRedirect =
StatusBadRequest =
StatusUnauthorized =
StatusPaymentRequired =
StatusForbidden =
StatusNotFound =
StatusMethodNotAllowed =
StatusNotAcceptable =
StatusProxyAuthRequired =
StatusRequestTimeout =
StatusConflict =
StatusGone =
StatusLengthRequired =
StatusPreconditionFailed =
StatusRequestEntityTooLarge =
StatusRequestURITooLong =
StatusUnsupportedMediaType =
StatusRequestedRangeNotSatisfiable =
StatusExpectationFailed =
StatusTeapot =
StatusInternalServerError =
StatusNotImplemented =
StatusBadGateway =
StatusServiceUnavailable =
StatusGatewayTimeout =
StatusHTTPVersionNotSupported =
)

Go语言学习笔记(六)net的更多相关文章

  1. Go语言学习笔记六: 循环语句

    Go语言学习笔记六: 循环语句 今天学了一个格式化代码的命令:gofmt -w chapter6.go for循环 for循环有3种形式: for init; condition; increment ...

  2. Go语言学习笔记(六) [包]

    日期:2014年7月30日   1.定义:包时函数和数据的集合.使用package关键字定义一个包,文件名不需要与包名一致,包名约定使用小写字符,Go包可以由多个文件组成,但是需要使用相同的packa ...

  3. HTML语言学习笔记(会更新)

    # HTML语言学习笔记(会更新) 一个html文件是由一系列的元素和标签组成的. 标签: 1.<html></html> 表示该文件为超文本标记语言(HTML)编写的.成对出 ...

  4. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  5. 2017-04-21周C语言学习笔记

    C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ...

  6. 2017-05-4-C语言学习笔记

    C语言学习笔记... ------------------------------------ Hello C语言:什么是程序:程序是指:完成某件事的既定方式和过程.计算机中的程序是指:为了让计算机执 ...

  7. Learning ROS for Robotics Programming Second Edition学习笔记(六) indigo xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  8. GO语言学习笔记(一)

    GO语言学习笔记 1.数组切片slice:可动态增长的数组 2.错误处理流程关键字:defer panic recover 3.变量的初始化:以下效果一样 `var a int = 10` `var ...

  9. Typescript 学习笔记六:接口

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  10. Haskell语言学习笔记(88)语言扩展(1)

    ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...

随机推荐

  1. 浅谈js中的正则表达式

    很多时候多会被正则表达式搞的晕头转向,最近抽出时间对正则表达式进行了系统的学习,整理如下: 正则表达式的创建 两种方法,一种是直接写,由包含在斜杠之间的模式组成:另一种是调用RegExp对象的构造函数 ...

  2. iOS-Core-Animation-Advanced-Techniques(一)

    视图(UIView)和图层(CALayer)的关系: 每一个UIview都有一个CALayer实例的图层属性,视图的职责就是创建并管理这个图层,以确保当子视图在层级关系中添加或者被移除的时候,他们关联 ...

  3. redis可视化客户端工具

    TreeNMS是一款redis,Memcache可视化客户端工具,采用JAVA开发,实现基于WEB方式对Redis, Memcached数据库进行管理.维护. 功能包括:NoSQL数据库的展示,库表的 ...

  4. 【源码分享】mui实现简单的手机音乐播放器

    mui实现简单的手机音乐播放器 最近先来无事,我用mui写了一个可以跨页面控制的音乐播放器.主要功能有上一曲,下一曲,播放,暂停,感兴趣的可以继续看下去. 说的总是不实在,直接上源码,有兴趣的可以读下 ...

  5. css的各种选择器

    一.基本选择器 1. * 通用元素选择器,匹配任何元素 2. E 标签选择器,匹配所有使用E标签的元素 3. .info class选择器,匹配所有class属性中包含info的元素 4. #foot ...

  6. 如何设计相对安全的cookie自动登录系统

    很多网站登录的时候,都会有一个"记住我"功能,用户可以在限定时间段内免登录, 比如豆瓣.人人.新浪微博等都有这种设计.这种技术其实就是基于 cookie的自动登录, 用户登录的时候 ...

  7. PHP数字价格格式化,保留两位小数

    number_format(($v['cash']/100),2); demo=>9,271.15

  8. 将Win7系统将默认打开的库改为计算机

  9. js禁止选中(网页复制)

    document.onselectstart=new Function("event.returnValue=false");//禁止选中(无法复制) document.oncon ...

  10. 【Android Developers Training】 93. 创建一个空验证器

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...