Pues menos mal que encontraste dónde estába el problema, porque yo no tenía ni idea

.
Respecto al Timer, hay que tener cuidado para que no se autobloquée. Por un lado comprueba cada cuánto tiempo se produce la alarma (evento), ya que si es demasiado rápido no le dará tiempo a dar la respuesta antes de que tenga que ejecutarse otra vez. Creo que había un método o propiedad que permitía "parar el reloj" y luego ponerlo otra vez en marcha.
El problema también puede estar aquí:
Código Delphi
[-]Msg := IdTCPClient1.ReadLn; if msg <> '' then ...
¿No hay otra forma de saber si hay mensajes pendientes? ¿O un evento en TCPClient que se ejecute cuando se reciban?