在网络世界里,进程间的通信离不开socket
,主要分为TCP Socket
和UDP Socket
。
下面以TCP
为例,分别写一下服务端
和客户端
。
这里要做的客户端
和服务端
,在连接建立后,都可以接收和发送消息。
首先定义三个事件回调:
// listener.go
package socketer
import "net"
// ConnectListener 连接建立回调
type ConnectListener func(conn net.Conn)
// ReceiveListener 收到消息回调
type ReceiveListener func(data []byte, conn net.Conn)
// CloseListener 连接关闭事件
type CloseListener func(conn net.Conn)
服务端
服务端主要实现:
- 初始化一个服务端
NewServer()
- 定义事件回调
OnConnect()
OnReceive()
OnClose()
- 开始监听
Listen()
// server.go
package socketer
import (
"bufio"
"io"
"net"
)
type Server struct {
listener net.Listener
address string
network string
closeListener CloseListener
receiveListener ReceiveListener
connectListener ConnectListener
}
func NewServer(network, address string) *Server {
return &Server{
network: network,
address: address,
}
}
func (s *Server) OnConnect(l ConnectListener) {
s.connectListener = l
}
func (s *Server) OnReceive(l ReceiveListener) {
s.receiveListener = l
}
func (s *Server) OnClose(l CloseListener) {
s.closeListener = l
}
func (s *Server) Send(conn net.Conn, data []byte) (int, error) {
return conn.Write(data)
}
func (s *Server) Close(conn net.Conn) error {
err := conn.Close()
if s.closeListener != nil {
s.connectListener(conn)
}
return err
}
func (s *Server) Listen() error {
var err error
s.listener, err = net.Listen(s.network, s.address)
if err != nil {
return err
}
for {
conn, err := s.listener.Accept()
if err != nil {
continue
}
if s.connectListener != nil {
s.connectListener(conn)
}
go s.accept(conn)
}
}
func (s *Server) accept(conn net.Conn) {
defer conn.Close()
reader := bufio.NewReader(conn)
for {
message, err := reader.ReadBytes('\n')
if err != nil {
if err == io.EOF {
s.Close(conn)
}
break
}
if s.receiveListener != nil {
go s.receiveListener(message, conn)
}
}
}
客户端
客户端主要实现
- 初始化一个客户端
NewClient()
- 定义事件回调
OnConnect()
OnReceive()
OnClose()
- 发送消息
Send()
- 接收消息
Recv()
,只接收一条消息 - 保持连接
Open()
,并持续接收消息,并触发消息回调
// client.go
package socketer
import (
"bufio"
"net"
)
type Client struct {
Conn net.Conn
address string
network string
closeListener CloseListener
receiveListener ReceiveListener
connectListener ConnectListener
}
func NewClient(network, address string) (*Client, error) {
var err error
client := &Client{
address: address,
network: network,
}
err = client.dial()
return client, err
}
func (c *Client) dial() error {
var err error
c.Conn, err = net.Dial(c.network, c.address)
if c.connectListener != nil {
c.connectListener(c.Conn)
}
return err
}
func (c *Client) Send(data []byte) (int, error) {
return c.Conn.Write(data)
}
func (c *Client) OnConnect(l ConnectListener) {
c.connectListener = l
}
func (c *Client) OnReceive(l ReceiveListener) {
c.receiveListener = l
}
func (c *Client) OnClose(l CloseListener) {
c.closeListener = l
}
func (c *Client) Close() error {
err := c.Conn.Close()
if c.closeListener != nil {
c.closeListener(c.Conn)
}
return err
}
func (c *Client) Recv() ([]byte, error) {
reader := bufio.NewReader(c.Conn)
return reader.ReadBytes('\n')
}
func (c *Client) Open() {
reader := bufio.NewReader(c.Conn)
defer c.Conn.Close()
for {
message, err := reader.ReadBytes('\n')
if err != nil {
break
}
if c.receiveListener != nil {
go c.receiveListener(message, c.Conn)
}
}
}
主要用法
首先服务端
定义好消息回调并开始监听:
serv := NewServer("tcp", "127.0.0.1:6000")
// 消息回调
serv.OnReceive(func(data []byte, conn net.Conn) {
fmt.Println("Server Received: ", string(data))
serv.Send(conn, []byte("ok\n"))
})
// 开始监听
serv.Listen()
然后在客户端,建立连接,并发送消息,接收消息:
client, err := NewClient("tcp", "127.0.0.1:6000")
if err != nil {
panic(err)
}
defer client.Close()
// 消息回调
client.OnReceive(func(data []byte, conn net.Conn) {
fmt.Println("Client Received: ", string(data))
})
// 发送消息
client.Send([]byte("啊哈哈\n"))
data, err := client.Recv()
if err != nil {
panic(err)
}
fmt.Println("Client Received: ", string(data))
// 如果想保持长连接,持续接收发送消息
client.Open()