go本地unix socket
common.go
package common
const (
SocketPath = "/run/test.sock"
)
type Request struct {
Age int `json:"age"`
}
type Response struct {
Err string `json:"err"`
}
client.go
package main
import (
"encoding/json"
"fmt"
"net"
"go-test/common"
)
func main() {
// 连接服务端
conn, err := net.Dial("unix", common.SocketPath)
if err != nil {
fmt.Printf("connect unix %s failed, err is %v\n", common.SocketPath, err)
return
}
defer conn.Close()
req := &common.Request{
Age: 17,
}
bytes, err := json.Marshal(req)
if err != nil {
fmt.Printf("marshal request failed, err is %v\n", err)
return
}
// 发送请求
if _, err = conn.Write(bytes); err != nil {
fmt.Printf("write request failed, err is %v\n", err)
return
}
// 读取响应
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
fmt.Printf("read response failed, err is %v\n", err)
return
}
resp := &common.Response{}
if err = json.Unmarshal(buf[:n], resp); err != nil {
fmt.Printf("json unmarshal response failed, err is %v", err)
return
}
fmt.Printf("read response %s\n", resp.Err)
}
server.go
package main
import (
"encoding/json"
"fmt"
"net"
"os"
"go-test/common"
)
func sendResponse(resp *common.Response, conn net.Conn) {
bytes, err := json.Marshal(resp)
if err != nil {
bytes = []byte(err.Error())
}
if _, err = conn.Write(bytes); err != nil {
fmt.Printf("conn write response failed, err is %v", err)
}
}
func main() {
os.Remove(common.SocketPath)
// 创建Unix套接字
listener, err := net.Listen("unix", common.SocketPath)
if err != nil {
fmt.Printf("listen unix socket %s failed, err is %v\n", common.SocketPath, err)
return
}
defer listener.Close()
// 等待客户端连接
conn, err := listener.Accept()
if err != nil {
fmt.Printf("listener accept failed, err is %v\n", err)
return
}
defer conn.Close()
// 读取客户端数据并响应
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
fmt.Printf("read client request data failed, err is %v\n", err)
return
}
req := common.Request{}
resp := &common.Response{}
if err := json.Unmarshal(buf[:n], &req); err != nil {
resp.Err = err.Error()
sendResponse(resp, conn)
return
}
fmt.Printf("receive age %d from client\n", req.Age)
resp.Err = "ok"
sendResponse(resp, conn)
}
go build -o client client/client.go
go build -o server server/server.go
问题:bind: address already in use
在创建Unix套接字之前不能创建这个文件,调用net.Listen函数会自动创建。
os.Remove(common.SocketPath)
os.Create(common.SocketPath)
listener, err := net.Listen("unix", common.SocketPath)