У меня есть TcpListener, который ждет новых соединений сокетов.Когда устанавливается новое соединение, некоторый другой код обслуживает сообщения от удаленного пользователя.Я периодически проверяю наличие новых подключений, и если создается новое, старое должно быть удалено.
Ранее я просто открывал новое подключение, которое по большей части работало нормально.Однако иногда у меня возникали проблемы с повторным использованием одного и того же порта, поэтому я решил, что было бы лучше закрыть это соединение (что, я думаю, должно также дать старому пользователю указание на то, что соединение прервалось).
приведенный ниже код является моей попыткой сделать это, но по какой-то причине вызов Disconnect блокируется на неопределенный срок.Есть ли способ остановить это?... или я что-то здесь упускаю?
while(1)
{
// FYI, m_server is a TcpListener^ and m_client is a TcpClient^
// Check for new client connections
if (m_server->Pending() == true)
{
if( m_stream != nullptr )
{
m_client->Client->Shutdown( SocketShutdown::Both ); // Stop sending / receiving
m_client->Client->Disconnect(true); // Disconnect the underlying network stream
m_client->Client->Close(); // Disconnect the underlying network stream
m_client->Close();
delete m_client;
m_client = nullptr;
}
m_client = m_server->AcceptTcpClient(); //grab the TCP client
m_stream = m_client->GetStream(); //create the stream at the same time
}
// ...go and service pending messages on the client stream
}
Документы по функции Disconnect () предполагают, что я могу установить время ожидания, но они не упоминают как?
Если вам нужно вызвать Disconnect без предварительного вызова Shutdown, вы можете установить для параметра DontLinger Socket значение false и указать ненулевой интервал времени ожидания, чтобы гарантировать, что данные, поставленные в очередь для исходящей передачи, отправляются.Затем отключите блоки, пока данные не будут отправлены или пока не истечет указанное время ожидания.Если для DontLinger задано значение false и указан нулевой интервал времени ожидания, Close освобождает соединение и автоматически отбрасывает исходящие данные в очереди.
[Edit] Я нашел решение дляпроблема тайм-аута при изменении m_client->Client->Disconnect(true);
на m_client->Client->Disconnect(false);
, но это все равно не предупреждает моего клиента, что сокет закрыт.Я перепробовал все, что мог придумать, чтобы проверить, но все они успешны:
// m_client is a TcpClient^
bool stillConnected = ( (m_client != nullptr) &&
(m_client->Connected == true) &&
(m_client->Client != nullptr) &&
(m_client->Client->Connected == true) );
stillConnected
всегда верно, даже после того, как другой клиент подключился к серверу и, следовательно, вызвал все биты выключения и куски выше,Это как отключение, которое я упомянул в начале моего вопроса, неправильно закрывает сокет или что-то в этом роде?