Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion pymodbus/client/tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,13 @@ def send(self, request, addr: tuple | None = None):
if not self.socket:
raise ConnectionException(str(self))
if request:
return self.socket.send(request)
try:
return self.socket.send(request)
except (BlockingIOError, InterruptedError):
raise
except OSError:
self.close()
raise ConnectionException(str(self)) from None
return 0

def recv(self, size: int | None) -> bytes:
Expand Down
24 changes: 24 additions & 0 deletions test/client/test_client_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,30 @@ def test_tcp_client_send(self):
assert not client.send(b"")
assert client.send(b"1234") == 4

def test_tcp_client_send_drops_socket_on_os_error(self):
"""Test that a socket the OS tore down is not left in place as connected."""
client = ModbusTcpClient("127.0.0.1")
mock_socket = mock.MagicMock()
mock_socket.send.side_effect = BrokenPipeError(32, "Broken pipe")
client.socket = mock_socket
with pytest.raises(ConnectionException):
client.send(b"1234")
assert not client.connected
assert client.socket is None

def test_tcp_client_send_keeps_socket_on_transient_error(self):
"""Test that a transient write error leaves a healthy socket in place."""
client = ModbusTcpClient("127.0.0.1")
mock_socket = mock.MagicMock()
mock_socket.send.side_effect = BlockingIOError(
11, "Resource temporarily unavailable"
)
client.socket = mock_socket
with pytest.raises(BlockingIOError):
client.send(b"1234")
assert client.connected
assert client.socket is mock_socket

@mock.patch("pymodbus.client.tcp.time")
@mock.patch("pymodbus.client.tcp.select")
def test_tcp_client_recv(self, mock_select, mock_time):
Expand Down