package main import ( "bufio" "fmt" "net" "os" "strings" "sync" log "github.com/sirupsen/logrus" ) var ( err error ) type TCPServer struct { Address string Port string Clients map[net.Conn]bool Mutex sync.Mutex LogWriter *bufio.Writer Reader *bufio.Reader Writer *bufio.Writer Conn net.Conn Listener net.Listener MsgChan chan string CmdChan chan string Log *log.Logger } func NewTCPServer(address string, port string, log *log.Logger) *TCPServer { return &TCPServer{ Address: address, Port: port, Clients: make(map[net.Conn]bool), MsgChan: make(chan string), CmdChan: make(chan string), Log: log, } } func (s *TCPServer) StartServer() { s.LogWriter = bufio.NewWriter(os.Stdout) s.Listener, err = net.Listen("tcp", Cfg.Telnet.Host+":"+Cfg.Telnet.Port) if err != nil { s.Log.Info("could not create telnet server") } defer s.Listener.Close() s.Log.Infof("telnet server listening on %s:%s", Cfg.Telnet.Host, Cfg.Telnet.Port) go func() { for message := range s.MsgChan { s.broadcastMessage(message) } }() for { s.Conn, err = s.Listener.Accept() s.Log.Info("client connected", s.Conn.RemoteAddr().String()) if err != nil { s.Log.Error("could not accept connections to telnet server") continue } s.Mutex.Lock() s.Clients[s.Conn] = true s.Mutex.Unlock() go s.handleConnection() } } func (s *TCPServer) handleConnection() { s.Conn.Write([]byte("Welcome to the FlexDXCluster telnet server! Type 'bye' to exit.\n")) s.Reader = bufio.NewReader(s.Conn) s.Writer = bufio.NewWriter(s.Conn) for { message, err := s.Reader.ReadString('\n') if err != nil { s.Mutex.Lock() delete(s.Clients, s.Conn) s.Mutex.Unlock() s.Log.Infof("client %s disconnected", s.Conn.RemoteAddr().String()) return } message = strings.TrimSpace(message) // if message is by then disconnect if message == "bye" { s.Mutex.Lock() delete(s.Clients, s.Conn) s.Mutex.Unlock() s.Log.Infof("client %s disconnected", s.Conn.RemoteAddr().String()) } if strings.Contains(message, "DX") && message != "SH/DX 30" { // send DX spot to the client s.CmdChan <- message } } } func (s *TCPServer) Write(message string) (n int, err error) { _, err = s.Writer.Write([]byte(message)) if err == nil { err = s.Writer.Flush() } return } func (s *TCPServer) broadcastMessage(message string) { s.Mutex.Lock() defer s.Mutex.Unlock() for client := range s.Clients { _, err := client.Write([]byte(message)) if err != nil { fmt.Println("error while sending message to clients:", client.RemoteAddr()) } } }