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);
}
} 7 17368
Michi Henning wrote: This looks like a bug in the .NET socket implementation to me. (The equivalent code in C++ works fine.)
I'm quite sure that this is a bug in the implementation of the Socket
class because I can get things to work by stepping down to the native API
with platform invoke.
Add the following definitions to the client:
[StructLayout(LayoutKind.Sequential)]
private struct in_addr
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
public byte[] sin_addr;
}
[StructLayout(LayoutKind.Sequential)]
private struct sockaddr
{
public short sin_family;
public ushort sin_port;
public in_addr sin_addr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=8)]
public byte[] sin_zero;
}
[DllImport("wsock32.dll")]
private static extern int getsockname(IntPtr s, ref sockaddr name, ref int namelen);
[DllImport("wsock32.dll")]
private static extern int getpeername(IntPtr s, ref sockaddr name, ref int namelen);
[DllImport("ws2_32.dll")]
private static extern IntPtr inet_ntoa(in_addr a);
[DllImport("ws2_32.dll")]
private static extern ushort ntohs(ushort netshort);
Then, at the end of the client, instead of reading the LocalEndPoint
and RemoteEndPonit properties, insert the following:
IntPtr socket = s.Handle;
sockaddr addr = new sockaddr();
int addrLen = 16;
getsockname(socket, ref addr, ref addrLen);
IntPtr str = inet_ntoa(addr.sin_addr);
Console.WriteLine(Marshal.PtrToStringAnsi(str) + ":" + ntohs(addr.sin_port));
getpeername(socket, ref addr, ref addrLen);
IntPtr str = inet_ntoa(addr.sin_addr);
Console.WriteLine(Marshal.PtrToStringAnsi(str) + ":" + ntohs(addr.sin_port));
This correctly prints the IP address and port number of the local and remote endpoint.
Cheers,
Michi.
Michi Henning <mi***@zeroc.com> wrote in message news:<#I**************@TK2MSFTNGP09.phx.gbl>... 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.
Michi -
The reason you can not retrieve the local or remote endpoints is
because there is no connection. When the socket is set to
non-blocking, the Connect() method throws a SocketException (only for
TCP connections), since the connection can not be established without
blocking. From the Socket class library page:
"The Connect method will block, unless you specifically set the
Blocking property to false prior to calling Connect. If you are using
a connection-oriented protocol like TCP and you do disable blocking,
Connect will throw a SocketException because it needs time to make the
connection."
Thus the connection is never established, and the local and remote
endpoint values are not set. If you do not set the Blocking property
to false, your code works fine.
If you do not want to block on the Connect(), try using the async
BeginConnect() version instead. Hope this helps shed some light on
your problem.
Rich Blum - Author
"C# Network Programming" (Sybex) http://www.sybex.com/sybexbooks.nsf/Booklist/4176
"Network Performance Open Source Toolkit" (Wiley) http://www.wiley.com/WileyCDA/WileyT...471433012.html
"Rich Blum" <ri*******@juno.com> wrote in message
news:cc**************************@posting.google.c om... The reason you can not retrieve the local or remote endpoints is because there is no connection.
No.
When the socket is set to non-blocking, the Connect() method throws a SocketException (only for TCP connections), since the connection can not be established without blocking. From the Socket class library page:
"The Connect method will block, unless you specifically set the Blocking property to false prior to calling Connect. If you are using a connection-oriented protocol like TCP and you do disable blocking, Connect will throw a SocketException because it needs time to make the connection."
Right. The man page says that. It also says that, if I connect in non-blocking
mode, the connection attempt is initiated, and that I should use poll() to
check
when the connection is established. Look at the code I sent -- it uses poll()
after the initial call to Connect() to wait until the socket becomes ready
for writing, which it does.
Thus the connection is never established, and the local and remote endpoint values are not set.
No. The connection is indeed established. If you actually run the code I sent,
you will see the server receiving the incoming connection request
and correctly printing the local and remote endpoint.
If you do not set the Blocking property to false, your code works fine.
Yes, but it also should work in non-blocking mode.
Have a look at my follow-up post. By using the native getsockname()
and getpeername() calls via platform invoke, the very same example
works just fine. The problem is definitely in the .NET Socket class
implementation.
If you do not want to block on the Connect(), try using the async BeginConnect() version instead. Hope this helps shed some light on your problem.
I considered that, but it doesn't solve my problem. What I need is the
connection attempt to be aborted after a set amount of time, not a
connection attempt that may block indefinitely (and tie up another
thread in the bargain).
Cheers,
Michi.
--
Michi Henning Ph: +61 4 1118-2700
ZeroC, Inc. http://www.zeroc.com
Hi!
This seems to be a bug in the framework, and I am following up with our
developers on this. However, I had a question for you. Why are you doing a
non-blocking connect and polling for the connect to succeed ? WHy dont you
use a BeginConnect./EndConnect() async pattern, and that will avoid this
issue totally.
feroze.
--
Remove "user" from the email address to reply to the author.
This posting is provided "AS IS" with no warranties, and confers no rights
Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm
"Michi Henning" <mi***@triodia.com> wrote in message
news:eA**************@TK2MSFTNGP11.phx.gbl... "Rich Blum" <ri*******@juno.com> wrote in message news:cc**************************@posting.google.c om...
The reason you can not retrieve the local or remote endpoints is because there is no connection. No.
When the socket is set to non-blocking, the Connect() method throws a SocketException (only for TCP connections), since the connection can not be established without blocking. From the Socket class library page:
"The Connect method will block, unless you specifically set the Blocking property to false prior to calling Connect. If you are using a connection-oriented protocol like TCP and you do disable blocking, Connect will throw a SocketException because it needs time to make the connection."
Right. The man page says that. It also says that, if I connect in
non-blocking mode, the connection attempt is initiated, and that I should use poll() to check when the connection is established. Look at the code I sent -- it uses
poll() after the initial call to Connect() to wait until the socket becomes ready for writing, which it does.
Thus the connection is never established, and the local and remote endpoint values are not set. No. The connection is indeed established. If you actually run the code I
sent, you will see the server receiving the incoming connection request and correctly printing the local and remote endpoint.
If you do not set the Blocking property to false, your code works fine.
Yes, but it also should work in non-blocking mode.
Have a look at my follow-up post. By using the native getsockname() and getpeername() calls via platform invoke, the very same example works just fine. The problem is definitely in the .NET Socket class implementation.
If you do not want to block on the Connect(), try using the async BeginConnect() version instead. Hope this helps shed some light on your problem.
I considered that, but it doesn't solve my problem. What I need is the connection attempt to be aborted after a set amount of time, not a connection attempt that may block indefinitely (and tie up another thread in the bargain).
Cheers,
Michi.
-- Michi Henning Ph: +61 4 1118-2700 ZeroC, Inc. http://www.zeroc.com
Feroze [MSFT] wrote: Hi!
This seems to be a bug in the framework, and I am following up with our developers on this. However, I had a question for you. Why are you doing a non-blocking connect and polling for the connect to succeed ? WHy dont you use a BeginConnect./EndConnect() async pattern, and that will avoid this issue totally.
BeginConnect()/EndConnect() have two problems:
- They tie up a thread for the duration of the connection attempt (which
may take quite a while).
- There is no way to adjust the timeout for the connection.
I'm in a situation where I want to establish a connection and
wait for a specified time for the attempt to succeed.
Even assuming that I could set a timeout for BeginConnect()
(which I can't), the async pattern then forces me to suspend
the calling thread after calling BeginConnect() and then wake up that
thread again from within the callback when it finally arrives.
That's a lot of hoops to jump through just to wait for a set amount of
time and also wastes an additional thread.
The code is a lot clearer if it stays all in one thread:
- put socket in non-blocking mode
- call Connect()
- catch SocketException and test for WSAEWOULDBLOCK
- call Select() with timeout
- Select() either times out or indicates that the connection was established
- if timeout, return error
- else get local and remote endpoint
Cheers,
Michi.
Michi Henning <mi***@zeroc.com> wrote in news:40**************@zeroc.com: - They tie up a thread for the duration of the connection attempt (which may take quite a while).
- There is no way to adjust the timeout for the connection.
Use a secondary thread to do the connect. Thats what Indy has an option to
do. I'm in a situation where I want to establish a connection and wait for a specified time for the attempt to succeed. Even assuming that I could set a timeout for BeginConnect() (which I can't), the async pattern then forces me to suspend the calling thread after calling BeginConnect() and then wake up that thread again from within the callback when it finally arrives. That's a lot of hoops to jump through just to wait for a set amount of time and also wastes an additional thread.
The code is a lot clearer if it stays all in one thread:
- put socket in non-blocking mode
- call Connect()
- catch SocketException and test for WSAEWOULDBLOCK
- call Select() with timeout
- Select() either times out or indicates that the connection was established
- if timeout, return error
- else get local and remote endpoint
Cheers,
Michi.
--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"
ELKNews - Get your free copy at http://www.atozedsoftware.com
Thanks a lot for this information. We appreciate the information your
provided for this issue. I will follow up with the developers.
Thanks a lot for reporting this bug.
feroze
-----------
This posting is provided as is, without warranties, and confers no
rights.
Michi Henning <mi***@zeroc.com> wrote in message news:<40**************@zeroc.com>... Feroze [MSFT] wrote:
Hi!
This seems to be a bug in the framework, and I am following up with our developers on this. However, I had a question for you. Why are you doing a non-blocking connect and polling for the connect to succeed ? WHy dont you use a BeginConnect./EndConnect() async pattern, and that will avoid this issue totally.
BeginConnect()/EndConnect() have two problems:
- They tie up a thread for the duration of the connection attempt (which may take quite a while).
- There is no way to adjust the timeout for the connection.
I'm in a situation where I want to establish a connection and wait for a specified time for the attempt to succeed. Even assuming that I could set a timeout for BeginConnect() (which I can't), the async pattern then forces me to suspend the calling thread after calling BeginConnect() and then wake up that thread again from within the callback when it finally arrives. That's a lot of hoops to jump through just to wait for a set amount of time and also wastes an additional thread.
The code is a lot clearer if it stays all in one thread:
- put socket in non-blocking mode
- call Connect()
- catch SocketException and test for WSAEWOULDBLOCK
- call Select() with timeout
- Select() either times out or indicates that the connection was established
- if timeout, return error
- else get local and remote endpoint
Cheers,
Michi. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: DBenson |
last post by:
So far I've been unable to find anything that addresses this one...
Basically, if I am logged in as root and issue a "php -m", mysql is in the
list of installed modules. If I log in or su to a...
|
by: kernel.lover |
last post by:
Hello,
i want to know to have multiple clients connects to same server
program does following is correct code
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include...
|
by: Ted |
last post by:
Hello all,
Please could somebody with a little time on their
hands help me with my net sockets program?
The aim is to send multiple transactions via C#
network stream and read them back. The...
|
by: BadOmen |
last post by:
Hi,
What is the different between 'System.Net.Sockets.Socket' and
'System.Net.Sockets.TcpClient'?
When do I use System.Net.Sockets.TcpClient and System.Net.Sockets.Socket??
Yours, Jonas
|
by: Robert McNally |
last post by:
Hello,
I'm currently learning c# and have been trying to write a simple program
with sockets.
The problem is i'm trying to send an email with an attachment, (which is the
program itself) by...
|
by: John Smith |
last post by:
How to find generlly "Secure Sockets Layer (SSL)" version for a given page?
Not through program.
John
|
by: Steven |
last post by:
Hi,
Thanks all for you help with my "socket and buffer size" question.
I have decided to use async ones, and my code is working pretty well.
But i still have a non-answered question:
Is it...
|
by: D. Patrick |
last post by:
I need to duplicate the functionality of a java applet, and how it connects
to a remote server. But, I don't have the protocol information or the java
source code which was written years ago. ...
|
by: Greg Young |
last post by:
Ok so I think everyone can agree that creating buffers on the fly in
an async socket server is bad ... there is alot of literature
available on the problems this will cause with the heap. I am...
|
by: rossabri |
last post by:
This topic has been addressed in limited detail in other threads:
"sockets don't play nice with new style classes :(" May 14 2005....
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
| |