前言
Golang 可以直接编译成各平台的二进制代码,并且处理网络很顺手。所以准备使用Golang来开发自己的小工具了。并且Go在大数据的处理上有很多优势,所以开始吧~~~
Golang Socket编程
网络模型回顾
Go socket编程
服务端和客户端
服务端
socket编程分为服务端编程和客户端编程,通俗的讲服务端就是等待连接的那个,客户段就是主动连接的那个。
我们先看看Golang服务端的编写,一个典型的Go 服务端的程序大致如下: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
37package main
import (
"fmt"
"net"
)
func main() {
// 监听端口,并处理错误
l, err := net.Listen("tcp", ":8888")
if err != nil {
fmt.Println("listen error:", err)
return
}
//处理连接
for {
c, err := l.Accept()
if err != nil {
fmt.Println("accept error", err)
break
}
go handleConn(c)
}
}
//处理连接
func handleConn(c net.Conn) {
defer c.Close()
for {
//从连接中读取数据
//......
//向连接中写入数据
//....
}
}
可以看到服务端使用到的函数是Listen和Accept,好像和python没什么区别嘛,但是Golang的服务端可以处理多个连接,而不像python需要自己处理多个请求,那让我们看看python是怎么处理多个请求的吧。
客户端
说完了服务端,现在看看客服端,只有客户端和服务端连接在以起才可以形成一个完整的连接。客户端使用Dail或者DailTimeout进行连接。
阻塞Dail:1
2
3
4
5
6conn, err := net.Dial("tcp", "baidu.com")
if err != nil {
//处理错误
}
//处理连接
带上超时机制的Dial:1
2
3
4
5
6conn, err := net.DialTimeout("tcp", "baidu.com", 2 * time.Second)
if err != nil {
//处理错误
}
//处理连接
当客户端准备去连接服务端的时候,会出现以下的几种情况。
3.1.2.1 网络不可达或对方服务未启动
如果传给Dial的Addr是可以立即判断出网络不可达,或者Addr中端口对应的服务没有启动,端口未被监听,Dial会几乎立即返回错误。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package main
import (
"log"
"net"
)
func main() {
log.Println("Begin dial....")
conn, err := net.Dial("tcp", ":8888")
if err != nil {
log.Println("dial error:", err)
return
}
defer conn.Close()
log.Println("dial OK")
}
结果:1
22018/03/03 00:35:31 Begin dial....
2018/03/03 00:35:32 dial error: dial tcp :8888: connectex: No connection could be made because the target machine actively refused it.
对方服务的Listen backlog满
Socket 读写
当客户端与服务端连接后,就可使用socket传输数据了。