Golang中实现一对多net.Conn连接的方法
Golang中实现一对多net.Conn连接的方法
我有一个本地的 net.Conn 连接和若干个远程连接。我需要从远程连接读取数据,将数据写入本地连接,从本地连接获取响应,然后将响应发送回最初发送消息的那个远程连接。这该如何实现?
2 回复
你如何从这些远程连接读取数据?能否展示一些相关代码?
更多关于Golang中实现一对多net.Conn连接的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中实现一对多的连接转发,可以使用连接映射和通道来管理。以下是一个实现示例:
package main
import (
"io"
"log"
"net"
"sync"
)
type ConnectionManager struct {
localConn net.Conn
remoteConns map[string]net.Conn
mu sync.RWMutex
}
func NewConnectionManager(local net.Conn) *ConnectionManager {
return &ConnectionManager{
localConn: local,
remoteConns: make(map[string]net.Conn),
}
}
func (cm *ConnectionManager) AddRemote(conn net.Conn) {
cm.mu.Lock()
defer cm.mu.Unlock()
cm.remoteConns[conn.RemoteAddr().String()] = conn
}
func (cm *ConnectionManager) RemoveRemote(addr string) {
cm.mu.Lock()
defer cm.mu.Unlock()
delete(cm.remoteConns, addr)
}
func (cm *ConnectionManager) ForwardToLocal(remote net.Conn) {
defer remote.Close()
// 为每个远程连接创建唯一标识
remoteAddr := remote.RemoteAddr().String()
// 从远程读取数据并写入本地
buf := make([]byte, 4096)
for {
n, err := remote.Read(buf)
if err != nil {
if err != io.EOF {
log.Printf("从远程读取错误: %v", err)
}
cm.RemoveRemote(remoteAddr)
return
}
// 写入本地连接
_, err = cm.localConn.Write(buf[:n])
if err != nil {
log.Printf("写入本地错误: %v", err)
return
}
// 从本地读取响应
respBuf := make([]byte, 4096)
respLen, err := cm.localConn.Read(respBuf)
if err != nil {
log.Printf("从本地读取错误: %v", err)
return
}
// 将响应写回对应的远程连接
_, err = remote.Write(respBuf[:respLen])
if err != nil {
log.Printf("写回远程错误: %v", err)
return
}
}
}
func main() {
// 建立本地连接
localConn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
log.Fatal(err)
}
defer localConn.Close()
cm := NewConnectionManager(localConn)
// 监听远程连接
listener, err := net.Listen("tcp", ":9090")
if err != nil {
log.Fatal(err)
}
defer listener.Close()
for {
remoteConn, err := listener.Accept()
if err != nil {
log.Printf("接受连接错误: %v", err)
continue
}
cm.AddRemote(remoteConn)
go cm.ForwardToLocal(remoteConn)
}
}
如果需要更精确的请求-响应匹配,可以使用带标识的协议:
type Request struct {
ID string
Data []byte
Conn net.Conn
}
func (cm *ConnectionManager) ForwardWithID(remote net.Conn) {
remoteAddr := remote.RemoteAddr().String()
requestChan := make(chan Request, 100)
responseChan := make(chan Request, 100)
// 读取远程请求
go func() {
buf := make([]byte, 4096)
for {
n, err := remote.Read(buf)
if err != nil {
close(requestChan)
return
}
requestChan <- Request{
ID: remoteAddr,
Data: append([]byte{}, buf[:n]...),
Conn: remote,
}
}
}()
// 处理请求和响应
for req := range requestChan {
// 写入本地
cm.localConn.Write(req.Data)
// 读取本地响应
respBuf := make([]byte, 4096)
respLen, _ := cm.localConn.Read(respBuf)
// 发送回对应远程连接
if req.Conn != nil {
req.Conn.Write(respBuf[:respLen])
}
}
}
这个实现确保了每个远程连接的请求都能获得对应的响应,通过连接映射管理多个远程连接与单个本地连接的通信。

