// Package lan expone la impresora por TCP en modo RAW (puerto 9100, // también llamado JetDirect / AppSocket), como las impresoras de red reales. package lan import ( "errors" "net" "escpos-emulator/internal/escpos" ) // Server acepta conexiones TCP y entrega los bytes a la impresora. type Server struct { ln net.Listener printer *escpos.Printer } // Listen abre el puerto y empieza a aceptar conexiones en segundo plano. func Listen(addr string, p *escpos.Printer) (*Server, error) { ln, err := net.Listen("tcp", addr) if err != nil { return nil, err } s := &Server{ln: ln, printer: p} go s.serve() return s, nil } // Addr devuelve la dirección en la que escucha. func (s *Server) Addr() net.Addr { return s.ln.Addr() } // Close deja de aceptar conexiones. func (s *Server) Close() error { return s.ln.Close() } func (s *Server) serve() { for { conn, err := s.ln.Accept() if err != nil { if errors.Is(err, net.ErrClosed) { return } continue } go s.handle(conn) } } func (s *Server) handle(conn net.Conn) { defer conn.Close() session := s.printer.NewSession("LAN "+conn.RemoteAddr().String(), func(b []byte) { _, _ = conn.Write(b) }) defer session.Close() buf := make([]byte, 4096) for { n, err := conn.Read(buf) if n > 0 { session.Write(buf[:n]) } if err != nil { return } } }