IM1
前期准备
IM 即时通讯,就是一端开放一个端口,并启动一个程序一直监听这个端口,当有人发送请求过来的时候接受然后处理;而另一端对那台机器的端口发送一个请求。
接受并处理的这一端我们通常称为服务端,发送的这一端我们通常成为客户端。
(此处表述并不严谨,有个了解即可)
客户端
接下来我们先专注于服务端,客户端暂时用 nc
命令模拟。
Server 端
首先构造一个 Server 结构体,装有 IP 和 Port 字段,并给他一个工厂函数用于返回 Server 实例。
| type Server struct {
IP string
Port int
}
func NewServer (IP string, Port int) *Server {
return &Server{IP, Port}
}
|
然后我们提供一个 Start 方法供实例调用,在方法中主要做4件事情:
- 创建一个监听对象,负责监听一个端口号
- 对发送来的请求进行接受,建立连接
- 开启一个
goroutine
进行处理
- 关闭监听对象
| func (s *Server) Start() {
address := fmt.Sprintf("%s:%d", s.IP, s.Port)
listener, err := net.Listen("tcp", address) // 创建一个监听对象
if err != nil {
fmt.Println("Listen err:", err)
return
}
defer listener.Close() // 延迟关闭监听对象
fmt.Println("=> Server listen on :", address)
for {
conn, err := listener.Accept() // 对发送来的请求进行接收,建立连接
if err != nil {
fmt.Println("Conn Err:", err)
}
go s.handler(conn) // 开启一个 goroutine 处理
}
}
|
| func (s *Server) handler(conn net.Conn) {
fmt.Println("Connection Successfuly.") // 服务端打印连接成功信息
conn.Write([]byte("Connection Successfuly.")) // 客户端打印连接成功信息
}
|
Server 结构体的逻辑写完后,就可以到 main()
函数中创建 server 对象了。
| func main() {
server := NewServer("127.0.0.1", 8088) // 实例化一个 server 对象
server.Start() // 调用 Start 方法开启服务
}
|
编译运行
执行命令:
| $ go build -o server main.go server.go
$ ./server
|
左侧为服务端,运行 ./server
后显示了服务监听着 127.0.0.1:8088
端口;
右侧为客户端,使用 nc
命令模拟,发送出请求后,服务端返回了 Connection Successfuly.
的字样,而服务端也打印出同样的字符串。
完整代码
Example
| // server.go
package main
import (
"fmt"
"net"
)
type Server struct {
IP string
Port int
}
func NewServer(IP string, port int) *Server {
return &Server{IP, port}
}
func (s *Server) Start() {
address := fmt.Sprintf("%s:%d", s.IP, s.Port)
// 1. listen
listener, err := net.Listen("tcp", address)
if err != nil {
fmt.Println("Listen err:", err)
return
}
// 4. close
defer listener.Close()
fmt.Println("=> Server listen on :", address)
for {
// 2. accept
conn, err := listener.Accept()
if err != nil {
fmt.Println("Conn Err:", err)
}
// 3. handle
go s.handler(conn)
}
}
func (s *Server) handler(conn net.Conn) {
fmt.Println("Connection Successfuly.")
conn.Write([]byte("Connection Successfuly."))
}
|
| // main.go
package main
func main() {
server := NewServer("127.0.0.1", 8088)
server.Start()
}
|