Socket编程
Socket编程是一种通过网络进行通信的编程技术,它允许不同计算机之间通过网络进行数据交换。Socket编程通常用于实现客户端-服务器模型,其中一个程序(服务器)等待连接,另一个程序(客户端)发起连接请求。Socket提供了底层的网络通信机制,使得程序能够通过网络传输数据。
详情请看 socket 到底是什么? | golang全栈指南 (opens new window)
在Go语言中,Socket编程可以通过net
包来实现。下面是简单的Go语言Socket编程示例
# 一、TCP连接
# 1. Server端
package main
import (
"bufio"
"fmt"
"net"
)
func main() {
// 监听指定端口
ln, err := net.Listen("tcp", ":8080")
if err != nil {
fmt.Println("Error listening:", err.Error())
return
}
defer ln.Close()
fmt.Println("Server is listening on port 8080...")
for {
// 接收客户端连接
conn, err := ln.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
return
}
// 处理客户端连接
go process(conn)
}
}
func process(conn net.Conn) {
// 处理完之后要关闭这个连接
defer conn.Close()
// 针对当前的连接做数据的发送和接收操作
for {
reader := bufio.NewReader(conn)
var buf [128]byte
n, err := reader.Read(buf[:])
if err != nil {
fmt.Printf("read from conn failed, err:%v\n", err)
break
}
recv := string(buf[:n])
fmt.Println("接收到的数据: ", recv)
conn.Write([]byte("OK")) // 回复客户端
}
}
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
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
# 2. Client端
package main
import (
"bufio"
"fmt"
"net"
"os"
"strings"
)
// tcp client demo
func main() {
// 1.与服务端建立连接
conn, err := net.Dial("tcp", "127.0.0.1:20000")
if err != nil {
fmt.Printf("dial failed, err:%v\n", err)
return
}
// 2.利用conn进行数据的发送和接收
input := bufio.NewReader(os.Stdin)
for {
s, _ := input.ReadString('\n')
s = strings.TrimSpace(s)
if strings.ToUpper(s) == "Q" {
return
}
// 给服务端发消息
_, err := conn.Write([]byte(s))
if err != nil {
fmt.Printf("send failed, err:%v\n", err)
return
}
// 从服务端接收回复的消息
var buf [1024]byte
n, err := conn.Read(buf[:])
if err != nil {
fmt.Printf("read failed, err: %v\n", err)
return
}
fmt.Println("收到服务端回复: ", string(buf[:n]))
}
}
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
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
# 二、UDP连接
# 1. Server端
package main
import (
"fmt"
"net"
)
// udp server demo
func main() {
listen, err := net.ListenUDP("udp", &net.UDPAddr{
IP: net.IPv4(127, 0, 0, 1),
Port: 30000,
})
defer listen.Close()
if err != nil {
fmt.Printf("listen failed, err: %v\n", err)
return
}
for {
var buf [1024]byte
n, addr, err := listen.ReadFromUDP(buf[:])
if err != nil {
fmt.Printf("read from udp failed, err: %v\n", err)
return
}
fmt.Printf("接收到来自%s的数据:%s\n", addr.String(), string(buf[:n]))
_, err = listen.WriteToUDP(buf[:n], addr)
if err != nil {
fmt.Printf("wtite to %v failed, err:%v\n", addr, err)
return
}
}
}
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
# 2. Client端
package main
import (
"bufio"
"fmt"
"net"
"os"
)
// udp client demo
func main() {
c, err := net.DialUDP("udp", nil, &net.UDPAddr{
IP: net.IPv4(127, 0, 0, 1),
Port: 30000,
})
defer c.Close()
if err != nil {
fmt.Printf("dial failed, err: %v\n", err)
return
}
// 发送数据
input := bufio.NewReader(os.Stdin)
for {
s, _ := input.ReadString('\n')
_, err = c.Write([]byte(s))
if err != nil {
fmt.Printf("send to server failed, err: %v\n", err)
return
}
// 接收数据
var buf [1024]byte
n, addr, err := c.ReadFromUDP(buf[:])
if err != nil {
fmt.Printf("recv from udp failed, err:%v\n", err)
return
}
fmt.Printf("read from%v,msg:%v\n", addr, string(buf[:n]))
}
}
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
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
上次更新: 2024/07/08, 18:19:51