62 lines
1.3 KiB
Go
62 lines
1.3 KiB
Go
package client
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
|
|
"git.lang-dieter.de/rs2322tcp/internal/transport"
|
|
)
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Data connection
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// OpenDataConnection opens the TCP data connection for the specified
|
|
// remote device.
|
|
//
|
|
// The DataPort is supplied by the server as part of the device information.
|
|
func (c *Client) OpenDataConnection(
|
|
device transport.RemoteDeviceInfo,
|
|
) (net.Conn, error) {
|
|
if c == nil || c.conn == nil {
|
|
return nil, fmt.Errorf("client is not connected")
|
|
}
|
|
|
|
if device.DataPort == 0 {
|
|
return nil, fmt.Errorf(
|
|
"device %q has no data port",
|
|
device.ID,
|
|
)
|
|
}
|
|
|
|
serverAddr := c.conn.RemoteAddr()
|
|
if serverAddr == nil {
|
|
return nil, fmt.Errorf("control connection has no remote address")
|
|
}
|
|
|
|
host, _, err := net.SplitHostPort(serverAddr.String())
|
|
if err != nil {
|
|
return nil, fmt.Errorf(
|
|
"invalid control server address %q: %w",
|
|
serverAddr.String(),
|
|
err,
|
|
)
|
|
}
|
|
|
|
dataAddr := net.JoinHostPort(
|
|
host,
|
|
fmt.Sprintf("%d", device.DataPort),
|
|
)
|
|
|
|
conn, err := net.Dial("tcp", dataAddr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf(
|
|
"connect data port %d for device %q: %w",
|
|
device.DataPort,
|
|
device.ID,
|
|
err,
|
|
)
|
|
}
|
|
|
|
return conn, nil
|
|
}
|