Просто чтобы прояснить, все TCPClients, на которые я ссылаюсь здесь, не являются экземплярами моего собственного класса, они все являются экземплярами System.Net.Sockets.TcpClient из реализации Mono .NET 4.0.
У меня есть сервер, который прослушивает подключения клиентов, как и серверы. Всякий раз, когда он получает нового клиента, он создает новый TCPClient для обработки соединения в новом потоке. Я отслеживаю все связи и темы со словарем. Если клиент отключается, он отправляет сообщение об отключении на сервер, TCPClient закрывается, словарная запись удаляется, и поток умирает естественным образом. Нет суеты, нет суеты. Сервер может обрабатывать несколько клиентов без проблем.
Тем не менее, я имитирую, что происходит, если клиент отключается, не имеет возможности отправить сообщение об отключении, а затем повторно подключается. Я выясняю, переподключился ли клиент с системой имени пользователя (это будет более безопасно, когда я закончу тестирование). Если я просто создаю новый TCPClient и оставляю старый запущенным, система работает нормально, но тогда у меня есть куча бесполезных потоков, которые занимают место и ничего не делают. Slackers.
Поэтому я пытаюсь закрыть TCPClient, связанный со старым соединением. Когда я это делаю, новый TCPClient также умирает, и клиентская программа выдает эту ошибку:
E/mono (12944): Unhandled Exception: System.IO.IOException: Write failure ---> System.Net.Sockets.SocketException: The socket has been shut down
И сервер выдает эту ошибку:
Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.
Cannot read from a closed TextReader.
Итак, закрытие старого TCPClient с удаленной конечной точкой скажем: 192.168.1.10:50001
Также разрывает новый TCPClient с удаленной конечной точкой, скажем: 192.168.1.10:50002
Таким образом, два объекта TCPClient имеют одинаковый IP-адрес удаленной конечной точки, но разные порты удаленной конечной точки. Но закрытие одного, кажется, мешает другому работать. Я хочу иметь возможность закрыть старый TCPClient для выполнения моей очистки, не закрывая новый TCPClient.
Я подозреваю, что это как-то связано с тем, как TCPClient работает с сокетами на низком уровне, но у меня нет реального понимания этого, я не могу это исправить.