473,221 Members | 1,782 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,221 software developers and data experts.

C#'s Socket.Connect returns normally but socket isn't connected.

I'm creating a socket as follows:

m_networkSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
m_networkSocket.LingerState = new LingerOption(true, 1);
m_networkSocket.Blocking = true;
m_networkSocket.SetSocketOption(SocketOptionLevel. Socket,
SocketOptionName.NoDelay, true);
m_networkSocket.SetSocketOption(SocketOptionLevel. Socket,
SocketOptionName.KeepAlive, !persistentConnection);

IPEndPoint them = new IPEndPoint(IPAddress.Parse(hostname), port);
try
{
m_networkSocket.Connect(them);
Debug.Assert(m_networkSocket.Connected,
"Connect() returned but we're not connected! Socket is: " +
m_networkSocket);
}
catch (SocketException se)
{
System.Console.WriteLine("connect caught: " + se);
}

After writing (synchronously) I close it thus:

m_networkSocket.Shutdown(SocketShutdown.Send);
m_networkSocket.Disconnect(false);
m_networkSocket.Close();
m_networkSocket = null;

The design requires that I open, write & close the socket for each message
I'm sending (the network might be unreliable, so a persistent connection
won't work). The whole thing runs in a single thread, taking messages out
of a queue (other threads insert messages into the queue).

The problem I've run into is that this works fine for the first block of
messages (I've tried batches of 16, 32 and 64 messages, with messages sent
in rapid succession). This first batch always works. I let a few seconds
pass, then send another batch. Sometimes the 2nd batch works, sometimes
not. If it fails it trips on the Debug.Assert immediately after the call
to Connect().

If it's returning from Connect() without throwing anything I'd _assumed_
that the connect worked - but the failure to pass the assertion tells me
other wise!

Anybody have any ideas as to what might be going on? I'm somewhat new to
socket programming, very new to Microsoft. We're using Visual Studio 2005
on XP Pro SP2.

thanks

--
Al Dunstan, Software Engineer
OptiMetrics, Inc.
3115 Professional Drive
Ann Arbor, MI 48104-5131
Sep 9 '08 #1
3 3012
On Tue, 09 Sep 2008 11:59:51 -0700, A. W. Dunstan <no@spam.thankswrote:
[...]
The problem I've run into is that this works fine for the first block of
messages (I've tried batches of 16, 32 and 64 messages, with messages
sent
in rapid succession). This first batch always works. I let a few
seconds
pass, then send another batch. Sometimes the 2nd batch works, sometimes
not. If it fails it trips on the Debug.Assert immediately after the call
to Connect().

If it's returning from Connect() without throwing anything I'd _assumed_
that the connect worked - but the failure to pass the assertion tells me
other wise!

Anybody have any ideas as to what might be going on? I'm somewhat new to
socket programming, very new to Microsoft. We're using Visual Studio
2005
on XP Pro SP2.
Fundamentally, the issue is that you're relying on a property that isn't
reliable. It won't return the instantaneous state of the socket, but
rather the state known at some previous time. Even if it did return the
instantaneous state, that state could change between the time you check it
and the time you try to rely on it.

When Connect() returns, the socket _has_ successfully connected to the
remote endpoint. However, you can't make any assumptions beyond that.
The internal data associated with the Connected property might not be
updated yet or the connection could wind up getting reset immediately
after connection. You simply need to write your code so that it can deal
with errors during later operations.

Speaking of which, given that, it really doesn't make sense to keep
recreating connections just because of a reliability issue. If anything,
the extra overhead _increases_ your exposure to reliability issues. Every
time any data is moved from one endpoint to the other, you run the risk of
a reliability problem causing an error. The only thing that recreating
connections does is cause _more_ data to be moved, increasing the risk of
an error.

Likewise, using the KeepAlive option will also have only that effect.
Given that the connections appear to be transient anyway, it's not clear
why you're using that. But given that you are, all it does is increase
your chances of having an error occur when one otherwise would not have.
Keep-alives can be useful in some very specific scenarios, but it's not an
appropriate approach to error management. That's not what it's there for.

Setting the Blocking property to "true" is superfluous. That's the
default.

Setting the NoDelay option is generally a bad idea, and it is especially
so in your particular scenario. It's bad generally because it decreases
efficiency of the connection. It's especially bad in your case for the
same reason that recreating the connection is: it has the effect of
_adding_ to the amount of data that needs to be moved, which increases
your odds of getting an error on the unreliable connection.

Finally, if you care about reliability, you should not rely on the
LingerState of the socket. Leave the socket as the default, and then
after you've called Shutdown(), call Receive() until it returns 0
(assuming the remote endpoint isn't actually going to send you anything,
that will happen as soon as the remote endpoint has received all of your
data). Unless you do that, you have no assurance that the remote endpoint
has actually received all of the data you sent, even using a lingering
socket.

In other words, I would take out almost all of the implementation details
you've posted, including the part of the design in which a new connection
is repeatedly reestablished. Just design the code so that it can recover
gracefully from a reset connection and otherwise leave the socket
connected. Don't bother with lingering, keep-alives, or disabling Nagle
(i.e. "NoDelay"), and do make sure you do a true graceful shutdown by
calling Receive() after Shutdown().

Right now, the code is written in a way that is likely to maximize the
number of errors. You're working against TCP, rather than with it.
That's never a good approach anyway, but especially when you _know_ you
have an unreliable connection, it's just going to hurt.

Pete
Sep 9 '08 #2
im new to .NET too, but the 64 open socket limit has always caused troubled.
Theres a way to increase ( if this limit still exist ) but i dont remember.
anyway, just a guess, probably not the right one.

"A. W. Dunstan" <no@spam.thanksescreveu na mensagem
news:Nf******************************@speakeasy.ne t...
I'm creating a socket as follows:

m_networkSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
m_networkSocket.LingerState = new LingerOption(true, 1);
m_networkSocket.Blocking = true;
m_networkSocket.SetSocketOption(SocketOptionLevel. Socket,
SocketOptionName.NoDelay, true);
m_networkSocket.SetSocketOption(SocketOptionLevel. Socket,
SocketOptionName.KeepAlive, !persistentConnection);

IPEndPoint them = new IPEndPoint(IPAddress.Parse(hostname), port);
try
{
m_networkSocket.Connect(them);
Debug.Assert(m_networkSocket.Connected,
"Connect() returned but we're not connected! Socket is: " +
m_networkSocket);
}
catch (SocketException se)
{
System.Console.WriteLine("connect caught: " + se);
}

After writing (synchronously) I close it thus:

m_networkSocket.Shutdown(SocketShutdown.Send);
m_networkSocket.Disconnect(false);
m_networkSocket.Close();
m_networkSocket = null;

The design requires that I open, write & close the socket for each message
I'm sending (the network might be unreliable, so a persistent connection
won't work). The whole thing runs in a single thread, taking messages out
of a queue (other threads insert messages into the queue).

The problem I've run into is that this works fine for the first block of
messages (I've tried batches of 16, 32 and 64 messages, with messages sent
in rapid succession). This first batch always works. I let a few seconds
pass, then send another batch. Sometimes the 2nd batch works, sometimes
not. If it fails it trips on the Debug.Assert immediately after the call
to Connect().

If it's returning from Connect() without throwing anything I'd _assumed_
that the connect worked - but the failure to pass the assertion tells me
other wise!

Anybody have any ideas as to what might be going on? I'm somewhat new to
socket programming, very new to Microsoft. We're using Visual Studio 2005
on XP Pro SP2.

thanks

--
Al Dunstan, Software Engineer
OptiMetrics, Inc.
3115 Professional Drive
Ann Arbor, MI 48104-5131

Sep 10 '08 #3
On Tue, 09 Sep 2008 17:07:15 -0700, Fernando <Fa************@hotmail.com>
wrote:
im new to .NET too, but the 64 open socket limit has always caused
troubled.
There is no such limit. Even on Win9x, you could have hundreds of sockets
open, and the NT-based OSs go _much_ higher than that.

You may be thinking of the 64-socket limit on WSAEventSelect (due to the
underlying limit in WaitForMultipleObjects), or in the legacy function
select. But there are simple ways to code around those, and it's not a
limit on the actual number of sockets, but just how many any given thread
can watch at once.

You'll note also that the OP's issue happens with a variety of numbers of
connections per "batch", not just 64, and doesn't happen 100% of the
time. So, I think that the issue here is unrelated to any physical limit
on the number of sockets and/or connections, inasmuch as any limitation
even exists.

Pete
Sep 10 '08 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: ETYC | last post by:
I am not sure if this is a bug or not but it seems strange to me. If I set the tcp socket blocking to false and do a connect, then I can catch the socketexception. If the exception is...
3
by: Daniel | last post by:
TcpClient close() method socket leak when i use TcpClient to open a connection, send data and close the TcpClient with myTcpClientInstance.Close(); it takes 60 seconds for the actual socket on...
3
by: Robert A. van Ginkel | last post by:
Hello Fellow Developer, I use the System.Net.Sockets to send/receive data (no tcpclient/tcplistener), I made a receivethread in my wrapper, the receivethread loops/sleeps while waiting for data...
6
by: Bruce Vander Werf | last post by:
I am using the asynchronous send/receive methods of the Socket class. When the remote end closes the socket, the callback for receive is called and EndReceive returns 0. Socket.Connected still...
5
by: John Sheppard | last post by:
Hi all, I am not sure that I am posting this in the right group but here it goes anyway. I am new to socket programming and I have been searching on the internet to the questions I am about to pose...
0
by: et-yc | last post by:
I am not sure if this is a bug or not but it seems strange to me. If I set the tcp socket blocking to false and do a connect, then I can catch the socketexception. If the exception is...
1
by: Dr. J | last post by:
I have an application that opens a socket and connects to another application listening over a port. The problem I am encountering is that when the listening application is closed my application...
2
by: Droopy | last post by:
Hi, I try to implement a reusable socket class to send and receive data. It seems to work but I have 2 problems : 1) I rely on Socket.Available to detect that the connection is closed (no...
10
by: John Salerno | last post by:
I wrote some pretty basic socket programming again, but I'm still confused about what's happening with the buffer_size variable. Here are the server and client programs: -------------- from...
0
by: veera ravala | last post by:
ServiceNow is a powerful cloud-based platform that offers a wide range of services to help organizations manage their workflows, operations, and IT services more efficiently. At its core, ServiceNow...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.