下面显示的代码几乎可以正常工作。如果我创建它的实例并调用“连接”,一切正常。当我调用“Disconnect”时,有时一切都很好(主要是如果我添加一个断点并慢慢地逐步执行该功能)。如果我不使用断点,那么类(作为win表单应用程序托管)似乎消失了(表单确实如此)但是visual studio仍然认为它正在运行。在visual studio的输出窗口中,我得到“System.dll中出现类型'System.ObjectDisposedException'的第一次机会异常”。谁能发现我做错了什么?
// State object for reading client data asynchronously
public class StateObject
{
private Guid ID = Guid.NewGuid();
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
}
public class NetworkComms : IBasePanel
{
private static ILog _log = LogManager.GetCurrentClassLogger();
// ManualResetEvent instances signal completion.
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false);
private static Socket _client = null;
private static IPEndPoint _endpoint = null;
public event ReceiveMessageEventHandler OnReceiveMessage;
public NetworkComms(string address, int port)
{
_endpoint = new IPEndPoint(GetIPAddress(address), port);
}
private IPAddress GetIPAddress(string address)
{
IPAddress ipAddress = null;
if (IPAddress.TryParse(address, out ipAddress))
{
return ipAddress;
}
else
{
IPHostEntry ipHostInfo = Dns.GetHostEntry(address);
return ipHostInfo.AddressList[ipHostInfo.AddressList.Count() - 1];
}
}
private void ConnectCallback(IAsyncResult ar)
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
_log.DebugFormat("Socket connected to {0}", client.RemoteEndPoint.ToString());
// Signal that the connection has been made.
connectDone.Set();
}
private void Receive()
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = _client;
// Begin receiving the data from the remote device.
_client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
private void ReceiveCallback(IAsyncResult ar)
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
ReceivedNewMessage(Encoding.Default.GetString(state.buffer, 0, bytesRead));
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
else
{
// Signal that all bytes have been received.
receiveDone.Set();
}
}
private static void SendCallback(IAsyncResult ar)
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
_log.DebugFormat("Sent {0} bytes to server.", bytesSent);
// Signal that all bytes have been sent.
sendDone.Set();
}
public void SendMessage(byte[] message)
{
_client.BeginSend(message, 0, message.Length, 0, new AsyncCallback(SendCallback), _client);
sendDone.WaitOne();
}
public void Connect()
{
_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_client.BeginConnect(_endpoint, new AsyncCallback(ConnectCallback), _client);
connectDone.WaitOne();
Receive();
}
public void Disconnect()
{
try
{
_client.Shutdown(SocketShutdown.Both);
_client.Close();
}
finally
{
_client = null;
connectDone.Reset();
sendDone.Reset();
receiveDone.Reset();
}
}
private void ReceivedNewMessage(string message)
{
if (this.OnReceiveMessage != null)
{
this.OnReceiveMessage(message);
}
}
public bool IsConnected
{
get
{
if (_client == null) return false;
return _client.Connected;
}
}
}
答案 0 :(得分:1)
所有回调都需要处理异常,这些异常在网络编程中相对常见。
在这种情况下,可能发生的事情是client.EndReceive(ar);
抛出了ObjectDisposedException,因为套接字在被调用时已经关闭。