Abel'Blog

我干了什么?究竟拿了时间换了什么?

0%

go-network

简介

golang在处理网络数据的时候,有天然的优势,这里记录一下如何使用golang来实现网络编程。

tcp

tcp server

下面是一个简单的示例,演示如何使用 Go 编写一个 TCP 服务器:

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
package main

import (
"fmt"
"net"
)

func handleConnection(conn net.Conn) {
defer conn.Close()

// 处理连接的逻辑
fmt.Println("Accepted connection from", conn.RemoteAddr())
conn.Write([]byte("Welcome to the server!\n"))
}

func main() {
// 监听端口
listener, err := net.Listen("tcp", ":8080")
if err != nil {
fmt.Println("Error listening:", err.Error())
return
}
defer listener.Close()

fmt.Println("Server is listening on port 8080")

for {
// 接受连接
conn, err := listener.Accept()
if err != nil {
fmt.Println("Error accepting connection:", err.Error())
return
}

// 启动一个 goroutine 处理连接
go handleConnection(conn)
}
}

websocket

提供一个简单的示例,包括一个WebSocket服务器程序和一个WebSocket客户端程序,用于实现消息定阅。

首先,让我们创建WebSocket服务器程序:

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
51
package main

import (
"fmt"
"net/http"

"github.com/gorilla/websocket"
)

var (
upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return true
},
}
)

func handleWebSocket(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
fmt.Println("Error upgrading to WebSocket:", err)
return
}
defer conn.Close()

for {
// 从客户端接收消息
_, msg, err := conn.ReadMessage()
if err != nil {
fmt.Println("Error reading message:", err)
break
}

fmt.Printf("Received message from client: %s\n", msg)

// 回复消息给客户端
err = conn.WriteMessage(websocket.TextMessage, []byte("Message received"))
if err != nil {
fmt.Println("Error writing message:", err)
break
}
}
}

func main() {
http.HandleFunc("/ws", handleWebSocket)
fmt.Println("WebSocket server started at :8080")
http.ListenAndServe(":8080", nil)
}

接下来,让我们创建一个简单的WebSocket客户端程序:

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package main

import (
"fmt"
"log"
"os"
"os/signal"
"time"

"github.com/gorilla/websocket"
)

func main() {
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)

url := "ws://localhost:8080/ws"
conn, _, err := websocket.DefaultDialer.Dial(url, nil)
if err != nil {
log.Fatal("Error connecting to WebSocket server:", err)
}
defer conn.Close()

done := make(chan struct{})

// 启动goroutine接收消息
go func() {
defer close(done)
for {
_, message, err := conn.ReadMessage()
if err != nil {
log.Println("Error reading message:", err)
return
}
fmt.Printf("Received message from server: %s\n", message)
}
}()

// 发送消息给服务器
message := []byte("Subscribe")
err = conn.WriteMessage(websocket.TextMessage, message)
if err != nil {
log.Println("Error writing message:", err)
return
}

// 模拟客户端保持活动状态
for {
select {
case <-time.After(5 * time.Second):
message := []byte("Ping")
err := conn.WriteMessage(websocket.TextMessage, message)
if err != nil {
log.Println("Error writing message:", err)
return
}
case <-interrupt:
log.Println("Interrupt signal received, closing connection.")
err := conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("Error closing connection:", err)
return
}
select {
case <-done:
case <-time.After(time.Second):
}
return
}
}
}

在这个示例中,WebSocket服务器在本地的8080端口上监听来自客户端的连接,并提供一个简单的处理函数来处理来自客户端的消息。WebSocket客户端连接到服务器并发送一个订阅消息,然后定期发送心跳消息以保持连接活动。您可以根据实际需求修改和扩展这些程序。