У меня есть служба, которая использует TcpListener для приема сообщений. Теоретически, связь между слушателем и клиентом (чей код находится вне моего контроля) должна оставаться открытой бесконечно долго. Я использую следующий (упрощенный) код для приема соединений.
while (DeviceState == State.Running)
{
// Wait for client connections to come in.
var incomingConnection = _tcpListener.AcceptTcpClient();
// Create a new thread to process this client connection.
var processThread = new Thread( ReceiveMessage );
processThread.Start( incomingConnection );
}
У меня есть возможность сбросить соединение, если в последнее время не было получено ни одного сообщения, что вызывает _tcpListener.Stop()
. Это вызывает исключение, потому что слушатель находится в блокирующем вызове AcceptTcpClient, но я нашел единственный способ остановить слушателя. Затем я пытаюсь создать новый TcpListener и запустить его. Это приводит к ошибке, говорящей о том, что порт заблокирован.
У меня есть три вопроса:
- Достаточно ли стабильно TcpListener для работы в течение нескольких месяцев без необходимости его сброса (ie. It никогда не попадет в состояние, в котором он не будет принимать соединение или сообщение)?
- Есть ли лучший способ остановить мой сервер, когда он ожидает блокирующего вызова (AcceptTcpClient) ?
- Если в некоторых случаях мне нужно будет сбросить соединение, есть ли способ закрыть TcpListener таким образом, чтобы не заблокировать порт, или способ разблокировать его, чтобы я мог восстановить соединение?
Я бы предпочел не работать на уровне сокетов, так как TcpListener делает то, что мне нужно, и когда я занимался программированием сокетов, прежде чем я, похоже, ввел столько же ошибок, сколько исправляю. Кроме того, я избегаю асинхронной связи, потому что входящие сообщения должны обрабатываться синхронно; новое сообщение не отправляется до тех пор, пока отправитель не получит подтверждение от предыдущего сообщения.