diff --git a/client/client.go b/client/client.go index af8b62a..2f5694b 100644 --- a/client/client.go +++ b/client/client.go @@ -5,41 +5,106 @@ import ( "log" "net" "smpptester/pdu" + "time" ) +const RETRY_TIMEOUT = 1 * time.Second + type SMPPClient struct { - Id int - conn net.Conn - port string - log log.Logger + Id int + Connected bool + enabled bool + running bool + conn net.Conn + port string + log log.Logger + dcErr chan (error) } func NewSMPPClient(port string, id int) *SMPPClient { client := &SMPPClient{ - Id: id, - port: port, - log: log.Logger{}, + Id: id, + port: port, + log: log.Logger{}, + dcErr: make(chan error, 128), } client.log = *log.New(log.Writer(), "", log.LstdFlags) client.log.SetPrefix(fmt.Sprintf("SMPP client %d: ", client.Id)) return client } -func (c *SMPPClient) Connect() error { +func (c *SMPPClient) Enable() { + if c.enabled { + c.log.Printf("SMPP client %d is already enabled", c.Id) + return + } + c.enabled = true + c.start() + c.log.Printf("SMPP client %d enabled", c.Id) +} +func (c *SMPPClient) Disable() { + if !c.enabled { + c.log.Printf("SMPP client %d is already disabled", c.Id) + return + } + c.enabled = false + c.dcErr <- fmt.Errorf("client is disabled") + if c.conn != nil { + c.conn.Close() + } + c.log.Printf("SMPP client %d disabled", c.Id) +} + +func (c *SMPPClient) start() { + if c.running { + c.log.Printf("SMPP client %d is already running", c.Id) + return + } + go func() { + c.running = true + defer func() { + c.running = false + }() + + c.log.Printf("SMPP client %d started", c.Id) + for { + if c.enabled && !c.Connected { + c.log.Printf("Trying to connect to %s", c.port) + err := c.connect() + if err != nil { + c.dcErr <- err + } + } + err := <-c.dcErr + c.Connected = false + if c.enabled { + c.log.Printf("Disconnected: '%v' trying again in %d second(s)", err, int(RETRY_TIMEOUT.Seconds())) + time.Sleep(RETRY_TIMEOUT) + } else { + c.log.Printf("Disconnected: '%v' & client is disabled, quitting", err) + break + } + } + }() +} + +func (c *SMPPClient) connect() error { + if !c.enabled { + return fmt.Errorf("client is not enabled") + } + if c.Connected { + return fmt.Errorf("client is already connected") + } conn, err := net.Dial("tcp", c.port) if err != nil { return fmt.Errorf("failed to connect to SMPP server: %w", err) } c.log.Printf("SMPP client %d connected to %s", c.Id, c.port) + c.Connected = true c.conn = conn return nil } -func (c *SMPPClient) Close() { - c.conn.Close() - c.log.Printf("SMPP client %d closed connection", c.Id) -} - func (c *SMPPClient) Send(pdata pdu.PDU) error { if c.conn == nil { return fmt.Errorf("connection is not established") @@ -54,9 +119,10 @@ func (c *SMPPClient) Send(pdata pdu.PDU) error { _, err = c.conn.Write(buf.Bytes()) if err != nil { + c.dcErr <- err return fmt.Errorf("failed to send PDU: %w", err) } c.log.Printf("SMPP client %d sent PDU: %+v", c.Id, pdata) return nil -} \ No newline at end of file +} diff --git a/main.go b/main.go index 820be1d..6ae51c7 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "encoding/binary" "log" "sync" + "time" "smpptester/client" "smpptester/pdu" @@ -171,14 +172,17 @@ func main() { wg.Add(1) client := client.NewSMPPClient("localhost:2775", 1) - err := client.Connect() - if err != nil { - log.Fatalf("Failed to connect to SMPP server: %v", err) - } - err = client.Send(submit) - if err != nil { - log.Fatalf("Failed to send PDU: %v", err) + client.Enable() + for { + if client.Connected { + err := client.Send(submit) + if err != nil { + log.Printf("Failed to send PDU: %v", err) + } + } + time.Sleep(10 * time.Millisecond) } + log.Println("Are we done") wg.Wait() } diff --git a/server/server.go b/server/server.go index f275077..72c9e2f 100644 --- a/server/server.go +++ b/server/server.go @@ -1 +1,66 @@ -package server \ No newline at end of file +package server + +import ( + "fmt" + "log" + "net" +) + +type SMPPServer struct { + Id int + conns []*net.Conn + listener net.Listener + port string + log log.Logger +} + +func NewSMPPServer(port string, id int) *SMPPServer { + server := &SMPPServer{ + port: port, + log: log.Logger{}, + Id: id, + } + server.log = *log.New(log.Writer(), "", log.LstdFlags) + server.log.SetPrefix(fmt.Sprintf("SMPP server %d: ", server.Id)) + return server +} + +func (s *SMPPServer) Listen() error { + listener, err := net.Listen("tcp", s.port) + if err != nil { + return fmt.Errorf("failed to start SMPP server: %w", err) + } + s.log.Printf("SMPP server %d started on %s", s.port) + s.listener = listener + return nil +} + +// package main + +// import ( +// "net" +// "fmt" +// ) + +// func main() { +// ln, err := net.Listen("tcp", ":8080") +// if err != nil { +// fmt.Println(err) +// return +// } +// defer ln.Close() + +// for { +// conn, err := ln.Accept() +// if err != nil { +// fmt.Println(err) +// continue +// } +// go handleConnection(conn) +// } +// } + +// func handleConnection(conn net.Conn) { +// defer conn.Close() +// // Handle the connection +// }