我正在寻求有关关闭侦听套接字的帮助。我遇到的问题是,当我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
}