I'm doing an application which require me as a client side to connect to a server and receive data from the server. I will need to do re-connection when the connection is disconnected. Below is my code:
public enum MySocketState
{
Disconnected = 0,
Connecting,
Connected
}
public Socket theDevSock = null;
public MySocketState sockState = MySocketState.Disconnected;
void DataProcess()
{
try
{
if (theDevSock == null || sockState == MySocketState.Disconnected)
{
Console.WriteLine("Trying to connect...");
StartConnect();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
public bool StartConnect(/*AsyncCallback requestCallback*/)
{
Socket theSocket = null;
try
{
Console.WriteLine("Start connect to server...");
theSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
theSocket.BeginConnect("192.168.1.10", 1000, ConnectCallback, theSocket);
sockState = MySocketState.Connecting;
return true;
}
catch (Exception ex)
{
Console.WriteLine("#### Unable to connect to server...");
}
CloseSocket();
return false;
}
void ConnectCallback(IAsyncResult ar)
{
try
{
theDevSock = (Socket)ar.AsyncState;
if (theDevSock != null)
{
if (theDevSock.Connected)
{
sockState = MySocketState.Connected;
Console.WriteLine("Server is connected...");
theDevSock.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, this.ReceiveCallback, theDevSock);
return;
}
}
Console.WriteLine("Failed to connect to server...");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
CloseSocket();
}
private void ReceiveCallback(IAsyncResult AR)
{
try
{
if (theDevSock == null)
theDevSock = (Socket)AR.AsyncState;
int recieved = theDevSock.EndReceive(AR); // Error occur in this line after re-connection.
if (recieved <= 0)
{
CloseSocket();
return;
}
byte[] recData = new byte[recieved];
Buffer.BlockCopy(_recieveBuffer, 0, recData, 0, recieved);
string strData = ASCIIEncoding.ASCII.GetString(recData);
Console.WriteLine(strData);
//Process the data stored in recData
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
CloseSocket();
}
finally
{
try
{
//Start receiving again
if (theDevSock != null)
theDevSock.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, ReceiveCallback, theDevSock);
}
catch (Exception ex2)
{ }
}
}
public void CloseSocket()
{
try
{
if (theDevSock != null)
{
if (theDevSock.Connected)
theDevSock.Shutdown(SocketShutdown.Both);
theDevSock.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
theDevSock = null;
sockState = MySocketState.Disconnected;
}
private void timer1_Tick(object sender, EventArgs e)
{
DataProcess();
}
}
I'm using a timer (timer1_tick) to always detect whether or not the server is connected.
The coding have no problem in reconnecting back to the server if the connection has been disconnected. The problem is after reconnection and when it receive the first data from the server, an error occur at line int recieved = theDevSock.EndReceive(AR)
. The error message is as below:
A first chance exception of type 'System.ArgumentException' occurred in System.dll
A first chance exception of type 'System.ObjectDisposedException' occurred in System.dll
System.ArgumentException: The IAsyncResult object was not returned from the corresponding asynchronous method on this class.
Parameter name: asyncResult
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult, SocketError& errorCode)
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at fform.ReceiveCallback(IAsyncResult AR) in c:\Work\Project 2015\Form1.cs:line 163
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult, SocketError& errorCode)
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at fform.Form1.ReceiveCallback(IAsyncResult AR) in c:\Work\Project 2015\Form1.cs:line 163
Why is it the IAsyncResult object was not returned?