Working on my RunUO Remote GUI thing...
So, basically, I'm doing async socket operations.
When I push a connect button on my form, I start by doing an async Dns.GetHostEntry to resolve the address of the server.
When it completes, I begin an async connect. Code:
Code:
#region Connecting and DNS
private void GetHostEntryCallback(IAsyncResult ar)
{
try
{
IPHostEntry e = Dns.EndGetHostEntry(ar);
if (e.AddressList.Length == 0)
throw new Exception("No address associated with hostname.");
m_Server.Address = e.AddressList[0];
BeginInternalConnect();
}
catch (Exception e)
{
QueueMessage(String.Format("[!] Resolve failed: {0}", e.Message));
}
}
public void BeginConnect()
{
IPAddress addr = null;
try
{
addr = IPAddress.Parse(m_Server.ServerHostName);
}
catch
{
addr = null;
}
if (addr == null)
{
QueueMessage(String.Format("[+] Resolving {0}...", m_Server.ServerHostName));
Dns.BeginGetHostEntry(m_Server.ServerHostName, new AsyncCallback(GetHostEntryCallback), null);
}
else
{
m_Server.Address = addr;
BeginInternalConnect();
}
}
public void BeginInternalConnect()
{
QueueMessage(String.Format("[+] Connecting to {0}...", m_Server.Address.ToString()));
IPEndPoint hostPoint = new IPEndPoint(m_Server.Address, m_Server.ServerPort);
try
{
m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_Socket.BeginConnect(hostPoint, new AsyncCallback(ConnectCallback), null);
}
catch (Exception e)
{
QueueMessage(String.Format("[!] Can't connect: {0}", e.Message));
m_Socket.Close();
m_Socket = null;
}
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
m_Socket.EndConnect(ar);
m_Connected = true;
QueueMessage(String.Format("[+] Connected to {0} ({1})", m_Server.ServerHostName, m_Server.Address));
m_Server.ConnectedAt = DateTime.Now;
}
catch (SocketException e)
{
m_Socket.Close();
m_Socket = null;
QueueMessage(String.Format("[!] Can't connect: {0}", e.Message));
}
catch
{
m_Socket.Close();
m_Socket = null;
QueueMessage("[!] Unknown error. Can't connect!");
}
}
#endregion
Entry point is BeginConnect(), which is called from another class.
Now, the problem is, sometimes I get this really annoying SocketException, goes like "The attempted operation is not supported for the type of object referenced."
The description from MSDN goes: "Operation not supported. The attempted operation is not supported for the type of object referenced. Usually this occurs when a socket descriptor to a socket that cannot support this operation is trying to accept a connection on a datagram socket."
It doesn't make a lot of sense. I'm not using a datagram socket, obviously. When I push connect the first time, I always get that exception thrown from BeginConnect, but if I push it again right after that, it works.
Getting it out of other WinSock functions too, like Disconnect. Really puzzling. So, am I just stupid? Something I'm not doing right?
I've tried it every different way I could think of. First I tried changing the way I use BeginConnect, by using a string to let it resolve itself, same thing. I tried a IPAddress instead of IPEndPoint. Same thing.
I thought maybe calling the BeginInternalConnect from the DNS callback might be a problem, so I tried having my worker thread do the call to BeginInternalConnect when the DNS was finished. Same thing.
Tried making ConnectCallback static and passing a reference to the object via AsyncResult, so I can access data from the instance. Same thing.
Any advise or insight would be greatly appreciate!