Socket.Connect fails after several successful attemps

T

Trollpower

Dear NG,

ive got the following problem. Ive made a client which makes a call to
a PHP-Script every 10 Seconds. The result of this call gets parsed.
The call is successfull all the time, but after about 70 calls the
code throws a exception at socket.connect().

Here is the code which i call every 10 Seconds. The method gets called
in a timerevent or in a thread with a waittime of 10 seconds. i tried
both, without success.

private string sendCommandToServer(string command){
connectCount++;
try
{
System.Net.Sockets.Socket socket = new
Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
IPAddress server = IPAddress.Parse("10.12.21.2");
IPEndPoint IPE = new IPEndPoint(server, Convert.ToInt32(80));
socket.Connect(IPE);
Byte[] msg = new Byte[command.Length+5];
msg = Encoding.Default.GetBytes(command+"\r\n");
StringBuilder data_string = new StringBuilder("");
Byte[] bytes = new Byte[1048576];
long bytes_read;
NetworkStream data_stream = new NetworkStream(socket);
int i, bloecke;
bloecke = 0;
socket.Send(msg);
bytes_read = socket.Receive(bytes);
while (bytes_read > 0)
{
for (i = 0; i < bytes_read; i++)
{
data_string.Append((char)(bytes));
}
bytes_read = socket.Receive(bytes);
bloecke = bloecke + 1;
}
socket.Close();
string answer = data_string.ToString();
return answer;
}
catch(Exception ex){
throw new Exception("ConnectionCounter = "+connectCount, ex);
}
}

The command is: POST http://fis.solutions/news.php?gid=4916094959292

If anyone can give me a hint what to do, i would really appreciate it.

Greeting

Jens
 
P

Paul G. Tobey [eMVP]

Most likely, you're ending up with a bunch of open sockets until those
Socket instances are actually deleted by the garbage collector. The best
way to verify that it's not a problem with the OS would be to duplicate the
code, but in C/C++, where you *know* when closesocket() is getting called,
and make sure that you aren't running into an OS limitation on recycling
sockets.

Obviously, one work-around would be to *not* create a new socket each time,
but use the same one and just reconnect, as necessary.

Paul T.
 
J

Jens Meyer

Dear Paul,

thank you very much for your answer. I will try the trick with the
global socket-Variable. I hope this helps. One last thing: I switched to
Webrequests in the same manner as i did the communication with the
sockets. This means that i declare a new Request-Variable each time i
call the method. The result is, that there are now errors, allthough i
declare and instantiate a new Webrequest and Webresponse -Variable on
each run.

Thank you again for your answer, i will try what you said.

Greetings

Jens
 
J

Jens Meyer

One last thing i forgot to mention: As the socket fails to connect, the
device itself refuses to make any connections. Even after i restart the
application. Using the visual debugger with the Visual Studio fails also
after the error occurs. Only if i pull the device out of the cradle and
put it back in, the whole stuff works again. This let me guess that it
has nothing to do with the Garbage Collector. After stopping the
application and restarting it, the variables should be cleared, right?
So there must be some kind of bug within the OS or within Activesync,
right? Btw the error occurs even if i raise the interval of the timer
calling the method to 30 seconds.

Thats very strange indeed. Maybe its some kind of bug which Microsoft
fails to notice?

Greetings

Jens
 
P

Paul G. Tobey [eMVP]

Just because the exit of the application doesn't fix it doesn't make it a
bug in the OS. It's quite possible that there is a global list of sockets
somewhere in the system. When a socket is closed, using closesocket(), that
item in the list is marked as recycling and, eventually, might be reused
(there's also a socket option to address that). It's possible that, if you
are consuming sockets at a high rate, the OS is not prepared to use the same
socket number again by the time you are otherwise out of new sockets to use.

On the other hand, it's also quite possible that the mere deletion of a
socket alone doesn't even call closesocket() in .NET CF. I do a lot of
network programming, but not much with .NET CF. If that were the case,
you'd be permanently consuming sockets (they'd never be marked in the global
table for recycling). That's why I suggested you do this all in C/C++,
where you are in total control, to see if it's an OS level thing or a
framework level thing...

Paul T.
 
G

Guest

Hi Paul,

Seems this is issue connected with transport level of Active Sync, Pocket PC
2003 emulator all works fine. Can you Paul test it on any network adapter in
real network, or may be you already have test results. Any information will
be usefull.

Thank you, Gen
 
P

Paul G. Tobey [eMVP]

At the moment, no, I don't have time. The emulator isn't really much of a
test, as it's actually running as a layer over the desktop network
components. If I can remember, I'll try something when I get a chance...

Paul T.
 
G

Guest

Hi Paul. I have some additional information, if use HttpWebRequest &
HttpWebResponse classes for this task it works fine. But if you remember this
objects locks connections for application on host where it was wrong
authorized 2 times.

Can you explain those strange things. Why i can create and dispose objects
HttpWebRequest & HttpWebResponse many times, (does this objects use sokcets?
:)). Why sockets doesn't works so many times like HttpWebRequest &
HttpWebResponse . I can't reuse sockets. if i make shutdown or/and close (I
have tested different cases) it thows exception with message =
"System.Net.Sockets.Socket" on connect method (please see previose answer
with recconect). If i don't close socket it throws excpetion (mmm... Socket
is already connected ) if don't make connect again (you ofcourse understude)
it is throws exception about closed connection on target host.
 
P

Paul G. Tobey [eMVP]

I don't have the source code for those objects, so no, I can't explain it.
A reasonable explanation, though, would be that you should be calling
Dispose for socket objects when you are done with them and those classes are
correctly doing that and you are not. Another reasonable explanation would
be that those objects are caching usable sockets and not counting on the
socket stack to recycle them and you are simply creating a new socket for
every new connection. How it might be accomplishing that when you can't, I
can't tell you, though.

Personally, I'd write a test in C or C++ and see if it's a socket problem or
a managed code library problem, as I said to begin with...

Paul T.
 
G

Guest

I have check disposing, Dispose invokes for each early opened socket

public class GtSocket: Socket
{
public GtSocket(AddressFamily addressFamily, SocketType
socketType, ProtocolType protocolType): base(addressFamily,
socketType, protocolType){}

protected override void Dispose(bool disposing)
{
base.Dispose (disposing);
WinAPI.closesocket(this.Handle); //to fire a control shot in head
}
}
 
G

Guest

Hello Paul, I have some additional info about .NET CF Socket. I hope that
this info will be usefull.
Really Socket.Connect doesn't fails, if you create , connect and close
socket.
But when after connect add code which will read and write to\from socket
it start fails on connect (on my PDA in USB cradle it fails on 83-85th
iteration).
 
G

Guest

Hello Paul, just have test native sockets from ws2.dll - seems it's a OS bug,
please read more about this bug in previose message.

Best regards.
 
P

Paul G. Tobey [eMVP]

I can certainly believe that communication over ActiveSync via sockets
doesn't work as well as network communication. Certainly, I've never seen
any sort of behavior where what you do with the socket after a connect
affects whether the connect succeeds or not...

Paul T.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top