M
Michi Henning
Hi,
I'm using a non-blocking connect to connect to a server.
Works fine -- the server gets and accepts the connection.
However, once the connection is established, I cannot
retrieve either the local or the remote endpoint from
the client-side socket.
The *really* strange thing is that Socket.LocalEndPoint is null.
According to the doc, that's impossible: reading the LocalEndPoint
or RemoteEndPoint property should either throw an exception or
give me a proper endpoint.
I've attached two very simple code snippets below. The server
simply sits and waits for an incoming connection on port 12345
on localhost. Once it has accepted an incoming connection, the
server sleeps for 10 seconds and then exits.
On the client side, I put the socket in non-blocking mode, initiate
the connection, and then use poll to wait for the socket descriptor
to become writeable (which indicates the the connection was completed).
At that point, LocalEndPoint and RemoteEndPoint are null, even though
the connection was successfully established (as evidenced by the output
from the server).
To run this, start the server in a window and the client in another window.
This looks like a bug in the .NET socket implementation to me. (The
equivalent code in C++ works fine.)
Can anyone help me out with this?
Thanks,
Michi.
using System;
using System.Net;
using System.Net.Sockets;
class Server
{
static void Main(string[] args)
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345));
s.Listen(1);
Socket c = s.Accept(); // Blocks until we get an incoming connection
Console.WriteLine((IPEndPoint)c.LocalEndPoint);
Console.WriteLine((IPEndPoint)c.RemoteEndPoint);
System.Threading.Thread.Sleep(10000);
}
}
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
class Client
{
static void Main(string[] args)
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Blocking = false; // We want to use non-blocking connect
try
{
s.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345)); // Initiate connection
}
catch (Win32Exception ex)
{
if (ex.ErrorCode == 10035) // WSAEWOULDBLOCK is expected, means connect is in progress
{
bool ready;
int repeatCount = 3;
do
{
ready = s.Poll(1000000, SelectMode.SelectWrite); // Wait until connection is complete
} while (!ready && --repeatCount > 0);
if (!ready)
{
Console.WriteLine("Connect failed");
Environment.Exit(1);
}
}
else
{
Console.WriteLine(ex);
Environment.Exit(1);
}
}
catch (System.Exception ex)
{
Console.WriteLine(ex);
Environment.Exit(1);
}
IPEndPoint lep = (IPEndPoint)s.LocalEndPoint;
Debug.Assert(lep != null); // Assertion fails!!!
IPEndPoint rep = (IPEndPoint)s.RemoteEndPoint;
Debug.Assert(rep != null); // Assertion fails!!!
Environment.Exit(0);
}
}
I'm using a non-blocking connect to connect to a server.
Works fine -- the server gets and accepts the connection.
However, once the connection is established, I cannot
retrieve either the local or the remote endpoint from
the client-side socket.
The *really* strange thing is that Socket.LocalEndPoint is null.
According to the doc, that's impossible: reading the LocalEndPoint
or RemoteEndPoint property should either throw an exception or
give me a proper endpoint.
I've attached two very simple code snippets below. The server
simply sits and waits for an incoming connection on port 12345
on localhost. Once it has accepted an incoming connection, the
server sleeps for 10 seconds and then exits.
On the client side, I put the socket in non-blocking mode, initiate
the connection, and then use poll to wait for the socket descriptor
to become writeable (which indicates the the connection was completed).
At that point, LocalEndPoint and RemoteEndPoint are null, even though
the connection was successfully established (as evidenced by the output
from the server).
To run this, start the server in a window and the client in another window.
This looks like a bug in the .NET socket implementation to me. (The
equivalent code in C++ works fine.)
Can anyone help me out with this?
Thanks,
Michi.
using System;
using System.Net;
using System.Net.Sockets;
class Server
{
static void Main(string[] args)
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345));
s.Listen(1);
Socket c = s.Accept(); // Blocks until we get an incoming connection
Console.WriteLine((IPEndPoint)c.LocalEndPoint);
Console.WriteLine((IPEndPoint)c.RemoteEndPoint);
System.Threading.Thread.Sleep(10000);
}
}
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
class Client
{
static void Main(string[] args)
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Blocking = false; // We want to use non-blocking connect
try
{
s.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345)); // Initiate connection
}
catch (Win32Exception ex)
{
if (ex.ErrorCode == 10035) // WSAEWOULDBLOCK is expected, means connect is in progress
{
bool ready;
int repeatCount = 3;
do
{
ready = s.Poll(1000000, SelectMode.SelectWrite); // Wait until connection is complete
} while (!ready && --repeatCount > 0);
if (!ready)
{
Console.WriteLine("Connect failed");
Environment.Exit(1);
}
}
else
{
Console.WriteLine(ex);
Environment.Exit(1);
}
}
catch (System.Exception ex)
{
Console.WriteLine(ex);
Environment.Exit(1);
}
IPEndPoint lep = (IPEndPoint)s.LocalEndPoint;
Debug.Assert(lep != null); // Assertion fails!!!
IPEndPoint rep = (IPEndPoint)s.RemoteEndPoint;
Debug.Assert(rep != null); // Assertion fails!!!
Environment.Exit(0);
}
}