Write tcp broken pipe error

I’ve got a go app that downloads files using github.com/jlaffaye/ftp which is a library that implements File Transfer Protocol (FTP)
Defined a struct with an FTP connection

type Client struct {
	conn *ftp.ServerConn
	sync.Mutex
}

I have a global client

var cli *Client = nil

Which I then initialize and assign to the global variable to be used later

	conn, err := ftp.Dial(cfg.Host+cfg.Port, ftp.DialWithContext(ctx))
	if err != nil {
		return fmt.Errorf("ftp dial error: %v", err)
	}

	err = conn.Login(cfg.Username, pwd)
	if err != nil {
		return fmt.Errorf("ftp login error: %v", err)
	}

	c := &Client{}

	c.Lock()
	c.conn = conn
	cli = c
	c.Unlock()

I’ve got a http handler that takes the conn field from the Client struct and calls

	fileNames, err := conn.NameList(".")
	if err != nil {
		return err
	}

Most of the time, the application fails on the call to conn.NameList(".") with error

write tcp xxx.xxx.xx.x:48572-\u003exx.xxx.xxx.xxx:21: write: broken pipe

And sometimes

write tcp xxx.xxx.xx.xx:63037-\u003exx.xxx.xxx.xxx:21: wsasend: An established connection was aborted by the software in your host machine

I don’t close the connection prematurely.
Does anyone have an idea on why this is happening? Or maybe you could recommend a better library that uses FTP?
As per a question if multiple services are running at the same time, and if it’s conccurently safe.

When a process is running, another can’t run until setIsRunning(false) is called

func (s *Service) setIsRunning(b bool) error {
	mu := &sync.Mutex{}
	mu.Lock()
	defer mu.Unlock()

	if b && s.isRunning {
		return errors.New("already running")
	}
	s.isRunning = b

	return nil
}

An attempt to call that handler while its running will yield
"error":"already running"

Also I use mutex locks while reading from the global Client like such

	cli.Lock()
	conn = cli.conn
	cli.Unlock()

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.