# TCP ports limitation explanations

According to the [Channel Access reference manual](https://epics.anl.gov/base/R7-0/6-docs/CAref.html#Unicast):
multiple {{CA}} servers
(one {{CA}} server per {{IOC_program}})
can run on the same {{host}} using the same UDP port number
(if a modern kernel is available),
but not using the same TCP port number.

The [recommended way](https://epics.anl.gov/base/R7-0/6-docs/CAref.html#Configurin2) to bypass this
limitation, is to **instantiate each {{IOC_program}} (and associated
{{CA}} server) with a different TCP port number** thanks to the
`EPICS_CAS_SERVER_PORT` environment variable.

So, in order to start the {{SSH_Monitor}} {{IOC_program}}
(e.g. the one monitoring `target1`,
used as an example in a previous [`.cmd` and `.substitutions` how-to](../how-to-guides/basics/cmd_and_sub_how_to.md) section),
run the following (e.g. on port `5066`):

```{code} bash
$ cd myTargetMonitoringTop/iocBoot/iocMyTargetMonitoring
$ vi st_target1.cmd

    > #!../../bin/linux-x86_64/myTargetMonitoring
    >
    > < envPaths
    >
  + > epicsEnvSet("EPICS_CAS_SERVER_PORT", "5066")
    > ...

$ ./st_target1.cmd
```

This way, you can run another {{IOC_program}} in parallel (in order to
monitor another {{target}}), e.g. if you also configured a `st_target2.cmd`
and a `target2.substitutions`, on port `5067`:

```{code} bash
$ cd myTargetMonitoringTop/iocBoot/iocMyTargetMonitoring
$ vi st_target2.cmd
        
    > #!../../bin/linux-x86_64/myTargetMonitoring
    >
    > < envPaths
    >
  + > epicsEnvSet("EPICS_CAS_SERVER_PORT", "5067")
    > ...

$ ./st_target2.cmd
```

```{important}
The most important thing to remember is to specify a different and unique port number for each
{{IOC_program}} running on the same {{host}}!
```

```{important}
When doing so, something also important to remember is to configure your firewall accordingly.
Based on the previous example, the following ports should be open:
TCP `5066`, TCP `5067`, UDP `5066` and UDP `5067`.

See [how to configure your firewall](../how-to-guides/basics/firewall_how_to.md#standard-firewall-configuration-for-epics)
for more details about how to open those ports.
```

```{seealso}
See the [`.cmd`, `.template` and `.substitutions` explanations](../explanations/cmd_and_template_and_sub_explanations.md)
in order to understand why you should run only one {{IOC_program}} per {{target}} to monitor.
```

```{tip}
[Here](https://epics-controls.org/resources-and-support/documents/howto-documents/channel-access-reach-multiple-soft-iocs-linux/)
is an alternative solution to try.
```

---

## Client-side implication of the TCP ports limitation

On the client side, due to the limitations discussed in the previous section, you will have to
specify the IP address **and TCP port numbers** of the {{SSH_Monitor}}
{{IOC_program}}s. This means no broadcast, only unicast. E.g. when using `caget`:

```{code} bash
EPICS_CA_AUTO_ADDR_LIST=NO EPICS_CA_ADDR_LIST="192.168.1.1:5066 192.168.1.1:5067" caget 'pv:name:toto'
```

```{important}
Similar configuration will be required, e.g. for:

* [Archiver Appliance](https://slacmshankar.github.io/epicsarchiver_docs/index.html)
* [Phoebus](https://github.com/ControlSystemStudio/phoebus) (see chapter 4 of the [official
  documentation](https://control-system-studio.readthedocs.io/_/downloads/en/latest/pdf/))
* `camonitor` (and `caget`, `caput` etc)
* For an [alarm server](../how-to-guides/basics/alarm_server_how_to.md).
* ...
* Well, **for any Channel Access client you can think of!**
```

```{admonition} 🚧 **WIP**/**TODO** 🚧
Is it possible to broadcast,
with `EPICS_CA_AUTO_ADDR_LIST=yes` client-side,
in order to avoid changing `EPICS_CA_ADDR_LIST` on every client,
every time a new {{IOC}} is added or when an old one is removed?

* Maybe it didn't work when testing because client and server broadcast addresses didn't match (see
  <https://epics.anl.gov/base/R7-0/6-docs/CAref.html#Broadcast>)?
* Maybe it didn't work when testing because an old kernel was used (and not a modern one).
* Maybe that a {{CA}} Gateway (and/or PVA Gateway) would allow broadcast?
```

```{admonition} 🚧 **WIP**/**TODO** 🚧
Is it possible to broadcast, even if `EPICS_CA_AUTO_ADDR_LIST=no` client-side,
but with `EPICS_CA_ADDR_LIST="192.168.1.255:5066 192.168.1.255:5067"` ?

* This configuration should work if the broadcast addresses are well configured (see
  <https://epics.anl.gov/base/R7-0/6-docs/CAref.html#Broadcast>).
```

```{tip}
If trying
[the alternative solution](https://epics-controls.org/resources-and-support/documents/howto-documents/channel-access-reach-multiple-soft-iocs-linux/)
(mentioned in the previous section),
then you won't have to unicast, broadcast is possible.
So `EPICS_CA_AUTO_ADDR_LIST` can be set to `yes`
and `EPICS_CA_ADDR_LIST` don't have to be set.
```
