Fix companion disconnect on inbound packet; use server.accept()

EthernetServer::available() returns any socket with data, including the
already-connected client's socket. The companion path then called stop()
on what it thought was a duplicate client, closing the shared socket and
disconnecting the companion after the first packet.

Switch both SerialEthernetInterface and EthernetCLI to server.accept(),
which only returns newly-accepted sockets. Removes the IP/port duplicate
detection in the companion path (no longer reachable) and the same-socket
early-return in the CLI path.

Reported by mcode6726 on PR #1983.
This commit is contained in:
Ryan Gregg
2026-05-18 21:04:09 +00:00
parent 87bed4946c
commit 40bd7d511b
2 changed files with 11 additions and 23 deletions
+5 -4
View File
@@ -98,12 +98,13 @@ static bool ethernet_handle_command(const char* command, char* reply) {
return false;
}
// Check for new TCP client connections, replacing any existing connection
// Check for new TCP client connections, replacing any existing connection.
// Use accept() (not available()) so we only see newly-accepted sockets;
// available() also returns existing connected sockets that have data, which
// would force us to disambiguate every inbound packet from a real new client.
static void ethernet_check_client() {
auto newClient = ethernet_server.available();
auto newClient = ethernet_server.accept();
if (newClient) {
// Only replace if this is actually a different client
if (newClient == ethernet_client && ethernet_client.connected()) return;
if (ethernet_client) ethernet_client.stop();
ethernet_client = newClient;
IPAddress ip = ethernet_client.remoteIP();
+6 -19
View File
@@ -120,34 +120,21 @@ bool SerialEthernetInterface::isWriteBusy() const {
}
size_t SerialEthernetInterface::checkRecvFrame(uint8_t dest[]) {
// check if new client connected; new connections replace existing ones
auto newClient = server.available();
// Use accept() (not available()) so we only see newly-accepted sockets.
// available() also returns existing connected sockets that have data,
// which would cause us to treat each inbound packet as a "new client"
// and stop() the underlying socket — disconnecting the companion.
auto newClient = server.accept();
if (newClient) {
IPAddress new_ip = newClient.remoteIP();
uint16_t new_port = newClient.remotePort();
ETHERNET_DEBUG_PRINTLN(
"New client available %u.%u.%u.%u:%u",
"New client accepted %u.%u.%u.%u:%u",
new_ip[0],
new_ip[1],
new_ip[2],
new_ip[3],
new_port);
if (client && client.connected()) {
IPAddress cur_ip = client.remoteIP();
uint16_t cur_port = client.remotePort();
ETHERNET_DEBUG_PRINTLN(
"Current client %u.%u.%u.%u:%u",
cur_ip[0],
cur_ip[1],
cur_ip[2],
cur_ip[3],
cur_port);
if (cur_ip == new_ip && cur_port == new_port) {
ETHERNET_DEBUG_PRINTLN("Ignoring duplicate client");
newClient.stop();
return 0;
}
}
deviceConnected = false;
if (client) {