// socket发送模块 // 秒寻科技 // zt 2024-09-30 package socketsend import ( "errors" "fmt" "ipsomc/core/dao/redis/redisapi" "ipsomc/module/socket/socketmodel" "ipsomc/public" "net" "strconv" "sync" "time" ) // 定义全局变量 var gSocket_UdpConn *net.UDPConn = nil // UDP句柄 var GSocket_mapTcpConn = make(map[string]*net.TCPConn) //TCP连接map var mapMutex sync.RWMutex type SocketSend struct { } // udp连接句柄 func (obj *SocketSend) SaveUdpConnHandle(udpConn *net.UDPConn) { mapMutex.Lock() defer mapMutex.Unlock() gSocket_UdpConn = udpConn } // 保存TCP连接句柄 func (obj *SocketSend) SaveTcpConnHandle(tcpConn *net.TCPConn, address string) { mapMutex.Lock() defer mapMutex.Unlock() GSocket_mapTcpConn[address] = tcpConn } // 删除TCP连接句柄 func (obj *SocketSend) DeleteTcpConnHandle(address string) { mapMutex.Lock() defer mapMutex.Unlock() delete(GSocket_mapTcpConn, address) } // 发送数据到基站 func (obj *SocketSend) SendDataToBts(projectId int, btsId int, apDataFrame []byte, wLen uint16) error { var redisObj redisapi.RedisApi udpClientAddr := &net.UDPAddr{} var udpClientAddrModel socketmodel.ClientAddr //客户端地址 //组织redis建值,并查询客户端IP与端口 redisKey := fmt.Sprintf("%08X", int(projectId)) + "-" + fmt.Sprintf("%08X", int(btsId)) //KEY if err := redisObj.GetModelData(redisKey, &udpClientAddrModel); err != nil { //删除map中的一个元素 public.PublicHeartMapDeleteOneItem(redisKey) return errors.New("该链接已过期") } //组织客户端地址 ip := make(net.IP, net.IPv4len) // 创建一个长度为4的切片,对应于 IPv4 地址 copy(ip, udpClientAddrModel.IP[:]) // 复制字节到切片 udpClientAddr.IP = ip udpClientAddr.Port = udpClientAddrModel.Port udpClientAddr.Zone = udpClientAddrModel.Zone //把数据发送至基站 _, err := gSocket_UdpConn.WriteToUDP(apDataFrame, udpClientAddr) if err != nil { return err } println("send data to bts", apDataFrame[0], apDataFrame[len(apDataFrame)-1], len(apDataFrame)) return nil } // 发送数据到基站 func (obj *SocketSend) SendDataToBtsTcp(projectId int, btsId int, apDataFrame []byte, wLen uint16) error { var redisObj redisapi.RedisApi var clientAddrModel socketmodel.ClientAddr //客户端地址 //组织redis建值,并查询客户端IP与端口 var maxRetries = 3 var existFlag = 0 redisKey := fmt.Sprintf("%08X", int(projectId)) + "-" + fmt.Sprintf("%08X", int(btsId)) //KEY for i := 0; i < maxRetries; i++ { if err := redisObj.GetModelData(redisKey, &clientAddrModel); err == nil { existFlag = 1 //找到了 break } time.Sleep(1 * time.Second) } //若不存在 if existFlag == 0 { public.PublicHeartMapDeleteOneItem(redisKey) //删除map中的一个元素 return errors.New("该链接已过期") } //获得tcp的连接 conn, exist := GSocket_mapTcpConn[clientAddrModel.Address] if exist { //把数据发送至基站 _, err := conn.Write(apDataFrame) if err != nil { return err } //获得系统工作模式 sysWorkMode := public.PublicSysWorkModeGet() if sysWorkMode == 0 { text := "Send " + strconv.Itoa(len(apDataFrame)) + " bytes to " + clientAddrModel.Address println(text) } } return nil }