go入门
Hireek 11/28/2022
# GO
gprc、grom、gin、go-micro...
# 指针
// * &
// 方法返回值为*T时,会发生内存逃逸。c语言则会error
func main() {
namePtr := new(string)
*namePtr = "Feng"
fmt.Println("namePtr :", namePtr)
fmt.Println("namePtr 值:", *namePtr)
name2 := "wwww"
name2Ptr := &name2
fmt.Println("name2Ptr :", name2Ptr)
fmt.Println("name2 值:", *name2Ptr)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# go/协程
# Go exit
# channel
无缓冲
有缓冲
for range
单向和双向管道
Select case
# Server Demo
package socket
import (
"fmt"
"net"
"strings"
)
func main() {
// 创建监听
ip := "127.0.0.1"
port := "8848"
address := fmt.Sprintf("%s:%d", ip, port)
listen, err := net.Listen("tcp", address)
if err != nil {
fmt.Println("register === err.Error()", err)
}
// Accept() (Conn, error)
conn, err := listen.Accept()
if err != nil {
fmt.Println("accept === err.Error()", err)
}
buf := make([]byte, 1024)
// Read(b []byte) (n int, err error)
cnt, err := conn.Read(buf)
if err != nil {
fmt.Println("conn.Read === err.Error()", err)
}
fmt.Println("收到客户端--->的数据,长度:", cnt, "数据:", string(buf))
serRes := strings.ToUpper(string(buf))
cnt, err = conn.Write([]byte(serRes))
fmt.Println("服务端发送--->客户端的数据,长度:", cnt, "数据:", serRes)
conn.Close()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# Client
package main
import (
"fmt"
"net"
"time"
)
func main() {
con, err := net.Dial("tcp", ":8848")
if err != nil {
fmt.Println("net.Dia === err.Error()", err)
return
}
fmt.Println("client连接建立成功")
for {
sendData := "Hello, world"
cnt, err := con.Write([]byte(sendData))
if err != nil {
fmt.Println("con.Write === err.Error()", err)
return
}
fmt.Println("客户端发送--->服务端的数据,长度:", cnt, "数据:", sendData)
buf := make([]byte, 1024)
cnt, err = con.Read(buf)
if err != nil {
fmt.Println("con.Read === err.Error()", err)
return
}
fmt.Println("客户端接收<----服务端的数据,长度:", cnt, "数据:", string(buf))
time.Sleep(1 * time.Second)
}
//con.Close()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# multiply socket Server
package main
import (
"fmt"
"net"
"strings"
)
func main() {
// 创建监听
ip := "127.0.0.1"
port := 8848
address := fmt.Sprintf("%s:%d", ip, port)
listen, err := net.Listen("tcp", address)
if err != nil {
fmt.Println("register === err.Error()", err)
return
}
fmt.Println("服务端监听ing...")
for {
// Accept() (Conn, error)
conn, err := listen.Accept()
if err != nil {
fmt.Println("accept === err.Error()", err)
}
go handle(conn)
}
}
func handle(conn net.Conn) {
fmt.Println("建立连接成功===", conn.RemoteAddr())
for {
buf := make([]byte, 1024)
// Read(b []byte) (n int, err error),阻塞
cnt, err := conn.Read(buf)
if err != nil {
fmt.Println("conn.Read === err.Error()", err)
}
fmt.Println("收到客户端--->的数据,长度:", cnt, "数据:", string(buf))
serRes := strings.ToUpper(string(buf))
cnt, err = conn.Write([]byte(serRes))
fmt.Println("服务端发送--->客户端的数据,长度:", cnt, "数据:", serRes)
}
// _ = conn.Close()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# Http-client
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
client := http.Client{}
resp, _ := client.Get("https://blog.alane.top")
body := resp.Body
all, _ := ioutil.ReadAll(body)
fmt.Println("====", string(all))
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# http-server
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
// 路由,func回调函数
http.HandleFunc("/user", func(writer http.ResponseWriter, request *http.Request) {
_, _ = io.WriteString(writer, "user返回")
})
if err := http.ListenAndServe("127.0.0.1:8080", nil); err != nil {
fmt.Println("server error ===", err)
return
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# json序列化
package main
import (
"encoding/json"
"fmt"
)
type Student struct {
Name string
Age int
Id int64
gender int
}
func main() {
feng := Student{
Id: 1,
Name: "feng",
Age: 18,
gender: 1, // 小写 json序列化会忽略
}
encodeInfo, err := json.Marshal(&feng)
if err != nil {
fmt.Println("json.Marshal(&feng)===", err)
return
}
fmt.Println("encodeInfo", string(encodeInfo))
var feng2 Student
if err := json.Unmarshal(encodeInfo,&feng2); err != nil {
fmt.Println("json.Unmarshal(&feng2)===", err)
return
}
fmt.Println("feng2",feng2)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Print...
encodeInfo {"Name":"feng","Age":18,"Id":1}
feng2 {feng 18 1 0}
1
2
2
# Json label
package main
import (
"encoding/json"
"fmt"
)
type Teacher struct {
Name string `json:"-"`
Age int `json:"age,string"`
Id int64
gender int
Address string `json:"address,omitempty""`
}
func main() {
tea := Teacher{
Name: "tea",
Age: 19,
Id: 1,
gender: 2,
Address: "",
}
encodeInfo, err := json.Marshal(&tea)
if err != nil {
fmt.Println("json.Marshal(&tea)===", err)
return
}
fmt.Println("encodeInfo", string(encodeInfo))
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 聊天室实现
# 需求
1. 上线下线
2. 聊天
3. 查询当前聊天室的用户名
4. 可以修改自己的名字rename
5. 超时退出
1
2
3
4
5
2
3
4
5
# 技术点分析
- socket、tcp编程
- map
- 存储用户
- 遍历
- map添加删除
- go程。通道
- Select模型(超时退出、主动退出)
- 定时器
# 实现步骤
socket
定义user
定义map
定义message通道
监听动作
# 测试tcp工具netcat
mac安装
brew install netcat
nc 127.0.0.1 8080 // 创建客户端
1
2
3
2
3