Я ищу помощь в отключении сокета для прослушивания, пожалуйста. У меня проблема в том, что когда я вызываю Shutdown()
непосредственно перед Close()
, один из этих двух вызовов, кажется, вызывает фиктивное чтение в сокете последних полученных данных. Как я могу остановить это, пожалуйста?
Мое приложение имеет две пары сокетов, как FTP. Один — это клиент, который подключается к удаленному серверу, а другой — сервер, который прослушивает и принимает второе соединение с удаленного хоста. Это входящее соединение подключено к асинхронному устройству OnReceived
для обработки нежелательных данных, поступающих с удаленного хоста.
Все это прекрасно работает, и обе розетки могут оставаться подключенными в течение нескольких дней или недель. Но если что-то пойдет не так, я реагирую тем, что закрываю все и начинаю заново. Во время вызова либо inboundSocket.Shutdown()
, либо inbounSocket.Close()
(не уверен, что это сложно отладить во втором потоке), я как будто перечитываю последний входящий пакет во входящем сокете. Тогда это вызывает еще больше проблем.
Как я могу отключиться. закрыть, отключить и т.д. и т.п., не заставляя это перечитывать?
Пример кода ниже, урезанный, чтобы показать мельчайшие детали.
Заранее спасибо.
Даниэль
public class TcpIpSenderReceiver
{
/// <summary>
/// Main thread, main entry point
/// </summary>
public void ConnectAndLogonAndStartReceivingInboundMessages()
{
CreateListenerAndStartListening();
AcceptInboundSocketAndHookUpDataReceiptCallBack();
}
/// <summary>
/// Main thread
/// </summary>
int CreateListenerAndStartListening()
{
tcpListener = new TcpListener(LocalBoundIpAddress, listeningPort);
tcpListener.Start();
}
/// <summary>
/// SECOND thread
/// </summary>
void AcceptInboundSocketAndHookUpDataReceiptCallBack()
{
int i = 0;
while (i < 100 && !tcpListener.Pending())
{
i++;
Thread.Sleep(100);
}
inboundSocket = tcpListener.AcceptSocket();
bufferForReceive = new byte[bufferSize];
WireUpCallbackForAsynchReceive();
}
/// <summary>
/// SECOND thread
/// </summary>
void WireUpCallbackForAsynchReceive()
{
if (asynchCallbackFunctionForReceive == null)
{
asynchCallbackFunctionForReceive = new AsyncCallback(OnDataReceived);
}
if (inboundSocket.Connected)
{
try
{
asyncResultForReceive = inboundSocket.BeginReceive(bufferForReceive, 0, bufferForReceive.Length, SocketFlags.None, asynchCallbackFunctionForReceive, null);
}
catch (Exception)
{
//...
}
}
}
/// <summary>
/// SECOND thread
/// </summary>
void OnDataReceived(IAsyncResult asyn)
{
// Read data call goes here.....
if (asyncResultForReceive != null)
{
inboundSocket.EndReceive(asyncResultForReceive);
}
WireUpCallbackForAsynchReceive(); // listen again for next inbound message
}
void Shutdown()
{
shouldAbortThread = true;
asyncResultForReceive = null;
asynchCallbackFunctionForReceive = null;
if (outboundStreamWriter != null)
{
try
{
outboundStreamWriter.Close();
outboundStreamWriter.Dispose();
outboundStreamWriter = null;
}
finally { }
}
if (outboundNetworkStream != null)
{
try
{
outboundNetworkStream.Close();
outboundNetworkStream.Dispose();
outboundNetworkStream = null;
}
finally { }
}
if (tcpClient != null)
{
try
{
tcpClient.Close();
tcpClient = null;
}
catch (SocketException)
{
// ...
}
}
if (inboundSocket != null)
{
try
{
// I think this is where it's puking
inboundSocket.Shutdown(SocketShutdown.Both);
inboundSocket.Close();
inboundSocket = null;
}
catch (SocketException)
{
//...
}
}
if (tcpListener != null)
{
try
{
tcpListener.Stop();
tcpListener = null;
}
catch (SocketException)
{
//...
}
}
}
#region Local variables
volatile bool shouldAbortThread;
TcpListener tcpListener;
TcpClient tcpClient;
StreamWriter outboundStreamWriter;
NetworkStream outboundNetworkStream;
Socket inboundSocket = null;
IAsyncResult asyncResultForReceive;
public AsyncCallback asynchCallbackFunctionForReceive;
byte[] bufferForReceive;
static string HostnameShared;
#endregion
}