只是demo,生产环境要防止粘包。可以作为多进程之间通讯。。。。
server
package main
import (
"fmt"
"net"
"os"
"os/signal"
"sync"
"syscall"
)
// 客户端连接结构
type Client struct {
Conn *net.UnixConn
}
var clients = make(map[*Client]bool)
var clientsLock = &sync.Mutex{}
func main() {
listener, err := net.ListenUnix("unix", &net.UnixAddr{Name: "my.sock", Net: "unix"})
if err != nil {
fmt.Println("Error listening:", err)
return
}
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
fmt.Println("Received interrupt, stopping...")
os.Remove("my.sock") // 移除 Unix 域套接字文件
os.Exit(1)
}()
defer listener.Close()
for {
conn, err := listener.AcceptUnix()
if err != nil {
fmt.Println("Error accepting:", err)
continue
}
client := &Client{Conn: conn}
clientsLock.Lock()
clients[client] = true
clientsLock.Unlock()
go handleConnection(client)
}
}
func handleConnection(client *Client) {
defer func() {
clientsLock.Lock()
delete(clients, client)
clientsLock.Unlock()
}()
buf := make([]byte, 1024)
for {
n, err := client.Conn.Read(buf)
if err != nil {
fmt.Println("Error reading:", err)
return
}
// 广播消息给所有客户端,除了发送者
broadcast(buf[:n], client)
}
}
func broadcast(message []byte, sender *Client) {
clientsLock.Lock()
defer clientsLock.Unlock()
for client, _ := range clients {
if client != sender {
client.Conn.Write(message)
}
}
}
client可以有多个,发消息给服务器,然后服务器进行转发
package main
import (
"bufio"
"fmt"
"net"
"os"
)
func main() {
conn, err := net.DialUnix("unix", nil, &net.UnixAddr{Name: "my.sock", Net: "unix"})
if err != nil {
fmt.Println("Error dialing:", err)
os.Exit(1)
}
defer conn.Close()
go func() {
input := bufio.NewScanner(os.Stdin)
for input.Scan() {
conn.Write([]byte(input.Text() + "\n"))
}
}()
buf := make([]byte, 1024)
for {
n, err := conn.Read(buf)
if err != nil {
fmt.Println("Error reading:", err)
return
}
fmt.Printf("Received data: %s\n", buf[:n])
}
}