Home All Groups Group Topic Archive Search About

Strange server socket behaviour

Author
25 Jan 2007 8:49 PM
Massimo
I'm facing quite a strange problem with a network server application.

This is quite a complex project, involving some embedded roaming clients
sending data to a central server using GPRS modems, and only the server part
is being developed using .NET: the clients uses C-language firmware running
on microcontrollers.

I'm not quite sure the clients' TCP/IP libraries really follow every
existing standard, so I can't be sure the problem isn't there (I'm quite
sure of the opposite, actually)... but they can connect without troubles to
any other TCP/IP network server in the world (ok, maybe this is exagerating
a bit, but you get the idea), so I think there must be some problem in the
server code.

The server is quite simple: it just sits there, waits for client
connections, accepts them and starts reading from the sockets until a server
shutdown is requested or the connection breaks. It never sends any data
because the client-server protocol is unidirectional, and it never closes
the connection, unless preliminary authentication fails or an error is
detected.

This is (roughly) the server's code:


----------
int firstpacketsize = 10;
int port = 42;
Socket serversocket = null;

void Start()
{
    serversocket = new
Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

    serversocket.Bind(new IPEndPoint(IPAddress.Any,port));

    serversocket.Listen(10);

    serversocket.BeginAccept(AcceptCallback,null);

    return;
}

void AcceptCallback(IAsyncResult ar)
{
    Socket clientsocket = serversocket.EndAccept(ar);

    string ip = (clientsocket.RemoteEndPoint as
IPEndPoint).Address.ToString();

    Console.WriteLine("Connection started from {0}",ip);

    byte[] packet = new byte[firstpacketize];

    Console.WriteLine("Waiting for first packet");

    int r =
clientsocket.Receive(packet,Protocol.AuthPacketSize,SocketFlags.None);

    // ...

    // Some error checking and client authentication code

    // ...

    // Now a new ClientConnection object is created and starts its own
    // asynchronous data reading and processing

    // ...

    serversocket.BeginAccept(AcceptCallback,null);

    return;
}
----------


This code works perfectly when the client is a .NET program, but crashes
when a connection is made by the "real" client. A SocketException is thrown
during the first clientsocket.Receive(), complaining about the connection
being forcibly closed by the remote host. But the worse is still to come:
after this error (and the subsequent clientsocket.Close()),
serversocket.BeginAccept() too throws an exception!

The client, of course, didn't close anything... or at least didn't want to.
I think there must be some nasty bug in the client's TCP/IP libraries,
because the server works flawlessly with a .NET client... but, as I said,
the clients seem to work ok when connecting to other network servers, so
maybe the problem's here and I'm not correctly handling some error that
usually doesn't happen but sometimes do.

What can I do to understand what's really happening here?

Do you see any flaw in my server code which could account for this behaviour
upon clientsocket.Receive()?

And how can an error in clientsocket.Receive() cause another error in
serversocket.BeginAccept()?!?

I'm really puzzled here...


Massimo

Author
26 Jan 2007 11:31 AM
Kevin Spencer
The remote client will certainly close the connection if your client socket
does not. Take a look at the following 2 articles on using an asynchronous
server socket:

http://www.codeguru.com/csharp/csharp/cs_misc/sampleprograms/article.php/c7695/#more
http://www.codeguru.com/Csharp/Csharp/cs_network/sockets/article.php/c8781/

The following tutorial may also be of help:
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=709

--
HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

The shortest distance between 2 points is a curve.

Show quote
"Massimo" <bar***@mclink.it> wrote in message
news:OClkJJMQHHA.468@TK2MSFTNGP02.phx.gbl...
> I'm facing quite a strange problem with a network server application.
>
> This is quite a complex project, involving some embedded roaming clients
> sending data to a central server using GPRS modems, and only the server
> part is being developed using .NET: the clients uses C-language firmware
> running on microcontrollers.
>
> I'm not quite sure the clients' TCP/IP libraries really follow every
> existing standard, so I can't be sure the problem isn't there (I'm quite
> sure of the opposite, actually)... but they can connect without troubles
> to any other TCP/IP network server in the world (ok, maybe this is
> exagerating a bit, but you get the idea), so I think there must be some
> problem in the server code.
>
> The server is quite simple: it just sits there, waits for client
> connections, accepts them and starts reading from the sockets until a
> server shutdown is requested or the connection breaks. It never sends any
> data because the client-server protocol is unidirectional, and it never
> closes the connection, unless preliminary authentication fails or an error
> is detected.
>
> This is (roughly) the server's code:
>
>
> ----------
> int firstpacketsize = 10;
> int port = 42;
> Socket serversocket = null;
>
> void Start()
> {
>    serversocket = new
> Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
>
>    serversocket.Bind(new IPEndPoint(IPAddress.Any,port));
>
>    serversocket.Listen(10);
>
>    serversocket.BeginAccept(AcceptCallback,null);
>
>    return;
> }
>
> void AcceptCallback(IAsyncResult ar)
> {
>    Socket clientsocket = serversocket.EndAccept(ar);
>
>    string ip = (clientsocket.RemoteEndPoint as
> IPEndPoint).Address.ToString();
>
>    Console.WriteLine("Connection started from {0}",ip);
>
>    byte[] packet = new byte[firstpacketize];
>
>    Console.WriteLine("Waiting for first packet");
>
>    int r =
> clientsocket.Receive(packet,Protocol.AuthPacketSize,SocketFlags.None);
>
>    // ...
>
>    // Some error checking and client authentication code
>
>    // ...
>
>    // Now a new ClientConnection object is created and starts its own
>    // asynchronous data reading and processing
>
>    // ...
>
>    serversocket.BeginAccept(AcceptCallback,null);
>
>    return;
> }
> ----------
>
>
> This code works perfectly when the client is a .NET program, but crashes
> when a connection is made by the "real" client. A SocketException is
> thrown during the first clientsocket.Receive(), complaining about the
> connection being forcibly closed by the remote host. But the worse is
> still to come: after this error (and the subsequent clientsocket.Close()),
> serversocket.BeginAccept() too throws an exception!
>
> The client, of course, didn't close anything... or at least didn't want
> to. I think there must be some nasty bug in the client's TCP/IP libraries,
> because the server works flawlessly with a .NET client... but, as I said,
> the clients seem to work ok when connecting to other network servers, so
> maybe the problem's here and I'm not correctly handling some error that
> usually doesn't happen but sometimes do.
>
> What can I do to understand what's really happening here?
>
> Do you see any flaw in my server code which could account for this
> behaviour upon clientsocket.Receive()?
>
> And how can an error in clientsocket.Receive() cause another error in
> serversocket.BeginAccept()?!?
>
> I'm really puzzled here...
>
>
> Massimo
>
Author
26 Jan 2007 6:13 PM
Massimo
"Kevin Spencer" <unclechut***@nothinks.com> ha scritto nel messaggio
news:OFQR41TQHHA.4276@TK2MSFTNGP02.phx.gbl...

> The remote client will certainly close the connection if your client
> socket does not. Take a look at the following 2 articles on using an
> asynchronous server socket:
>
> http://www.codeguru.com/csharp/csharp/cs_misc/sampleprograms/article.php/c7695/#more
> http://www.codeguru.com/Csharp/Csharp/cs_network/sockets/article.php/c8781/
>
> The following tutorial may also be of help:
> http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=709

I'm sorry?
What do you exactly mean?

I already have a perfectly working server that uses asynchronous sockets :-)

The problem is, when this particular device connects to it, the behaviour I
described surfaces. When I connect from a .NET client program, it works
flawlessly.

Why should the remote client close the connection? Its C code isn't telling
him to do this, its code says "open a connection to this server on this port
and keep it open". But when the server tries to Receive() from the newly
accepted connection, it gets that SocketException saying the connection was
closed from the remote host. It should just blocks waiting for data,
shouldn't it? It does, when a .NET client connects. This is the reason I
think there are some bugs in the device's TCP/IP libraries. But the device
can open a connection to an Internet web server, so maybe its TCP/IP
works... and there's something wrong in my server.

It's a strange problem, I agree... but I don't think a socket tutorial is
what I'm in need of :-)


Massimo
Author
26 Jan 2007 8:01 PM
Barry Kelly
Massimo wrote:

> Why should the remote client close the connection? Its C code isn't telling
> him to do this, its code says "open a connection to this server on this port
> and keep it open". But when the server tries to Receive() from the newly
> accepted connection, it gets that SocketException saying the connection was
> closed from the remote host. It should just blocks waiting for data,
> shouldn't it? It does, when a .NET client connects. This is the reason I
> think there are some bugs in the device's TCP/IP libraries. But the device
> can open a connection to an Internet web server, so maybe its TCP/IP
> works... and there's something wrong in my server.

I think you need to break out a packet analyser like Wireshark or
similar, and see what's going on over the wires.

-- Barry

Author
26 Jan 2007 11:10 PM
Goran Sliskovic
Barry Kelly wrote:
Show quote
> Massimo wrote:
>
>> Why should the remote client close the connection? Its C code isn't telling
>> him to do this, its code says "open a connection to this server on this port
>> and keep it open". But when the server tries to Receive() from the newly
>> accepted connection, it gets that SocketException saying the connection was
>> closed from the remote host. It should just blocks waiting for data,
>> shouldn't it? It does, when a .NET client connects. This is the reason I
>> think there are some bugs in the device's TCP/IP libraries. But the device
>> can open a connection to an Internet web server, so maybe its TCP/IP
>> works... and there's something wrong in my server.
>
> I think you need to break out a packet analyser like Wireshark or
> similar, and see what's going on over the wires.
>
> -- Barry
>

Yes, packet analyzer should do the trick (Ethereal is also good). I
suspect the client is doing send() followed by immediate close()
(non-linger mode) on socket. Which leads to data + rst segment sent.

Just a hunch :)

Regards,
Goran
Author
27 Jan 2007 3:36 AM
Massimo
"Goran Sliskovic" <gslis***@yahoo.com> ha scritto nel messaggio
news:eRekc8ZQHHA.4000@TK2MSFTNGP04.phx.gbl...

> Yes, packet analyzer should do the trick (Ethereal is also good). I
> suspect the client is doing send() followed by immediate close()
> (non-linger mode) on socket. Which leads to data + rst segment sent.

Can you elaborate about this, or give me some links to more info?


Massimo
Author
31 Jan 2007 5:48 PM
Goran Sliskovic
"Massimo" <bar***@mclink.it> wrote in message
news:O1icWRcQHHA.1200@TK2MSFTNGP04.phx.gbl...
> "Goran Sliskovic" <gslis***@yahoo.com> ha scritto nel messaggio
> news:eRekc8ZQHHA.4000@TK2MSFTNGP04.phx.gbl...
>
> > Yes, packet analyzer should do the trick (Ethereal is also good). I
> > suspect the client is doing send() followed by immediate close()
> > (non-linger mode) on socket. Which leads to data + rst segment sent.
>
> Can you elaborate about this, or give me some links to more info?
>
>
> Massimo

It's just a thought... I suppuse you receive RST segment, becuase error is
WSEACONRESET. This is probably cuased by client calling close on socket.
When TCP stack receives RST, it will discard any pending (not removed from
read buffer and not sent) packets and signal  WSEACONRESET on all subsequent
operation (read & write). So even if incoming data is already buffered, recv
will return that error. But it's hard to tell without actually seeing the
trace/client source.

Check:
http://groups.google.hr/group/microsoft.public.win32.programmer.networks/browse_thread/thread/56929d755af9619f/f7674d05ed602d8c?lnk=st&q=socket+rst+receive+buffer&rnum=8&hl=hr#f7674d05ed602d8c

Regards,
Goran
Author
31 Jan 2007 7:07 PM
Massimo
"Goran Sliskovic" <gslis***@yahoo.com> ha scritto nel messaggio
news:%23pS7EAWRHHA.1180@TK2MSFTNGP05.phx.gbl...

>> > Yes, packet analyzer should do the trick (Ethereal is also good). I
>> > suspect the client is doing send() followed by immediate close()
>> > (non-linger mode) on socket. Which leads to data + rst segment sent.
>>
>> Can you elaborate about this, or give me some links to more info?
>
> It's just a thought... I suppuse you receive RST segment, becuase error is
> WSEACONRESET. This is probably cuased by client calling close on socket.

The problem is, the client isn't doing any Close() at all!
It just does Connect() (in its own way) and sits there waiting for the
connection to be established. At this point, the server's EndAccept()
triggers, the new socket is istantiated, and then the server does Receive(),
waiting for some data to be sent from the client. Now the client should
complete its Connect() succesfully... but it never does. It neither logs an
error: the Connect() never returns. But the server gets a SocketException
from its Receive(), saying the connection was closed by the client.
Absolutely ugly :-(


Massimo
Author
1 Feb 2007 10:31 AM
Goran Sliskovic
Show quote
"Massimo" <bar***@mclink.it> wrote in message
news:uq4NVsWRHHA.1200@TK2MSFTNGP02.phx.gbl...
....
> The problem is, the client isn't doing any Close() at all!
> It just does Connect() (in its own way) and sits there waiting for the
> connection to be established. At this point, the server's EndAccept()
> triggers, the new socket is istantiated, and then the server does
Receive(),
> waiting for some data to be sent from the client. Now the client should
> complete its Connect() succesfully... but it never does. It neither logs
an
> error: the Connect() never returns. But the server gets a SocketException
> from its Receive(), saying the connection was closed by the client.
> Absolutely ugly :-(
....

Is that some kind of routed network/dialup?

Goran
Author
1 Feb 2007 6:55 PM
Massimo
"Goran Sliskovic" <gslis***@yahoo.com> ha scritto nel messaggio
news:%23LNllweRHHA.1200@TK2MSFTNGP02.phx.gbl...

> Is that some kind of routed network/dialup?

See the original post for details.


Massimo
Author
2 Feb 2007 11:29 AM
Goran Sliskovic
"Massimo" <bar***@mclink.it> wrote in message
news:eTPUZKjRHHA.1212@TK2MSFTNGP03.phx.gbl...
> "Goran Sliskovic" <gslis***@yahoo.com> ha scritto nel messaggio
> news:%23LNllweRHHA.1200@TK2MSFTNGP02.phx.gbl...
>
> > Is that some kind of routed network/dialup?
>
> See the original post for details.
....
Ah, sorry, it was few days ago. It's hard to tell without the actual packet
trace, but it maybe the problem with routing. Since client never finishes
connect, but server receives connection, there may be problem for packets
from server reaching client (NAT, firewall, routes). I'm not sure though
when accept event is signal on socket, when SYN packet is received or when
3-way handshake has completed. Anyone?

Regards,
Goran
Author
2 Feb 2007 5:29 PM
Massimo
Show quote
"Goran Sliskovic" <gslis***@yahoo.com> ha scritto nel messaggio
news:u3Syv1rRHHA.3996@TK2MSFTNGP04.phx.gbl...

>> > Is that some kind of routed network/dialup?
>>
>> See the original post for details.
> ...
> Ah, sorry, it was few days ago. It's hard to tell without the actual
> packet
> trace, but it maybe the problem with routing. Since client never finishes
> connect, but server receives connection, there may be problem for packets
> from server reaching client (NAT, firewall, routes). I'm not sure though
> when accept event is signal on socket, when SYN packet is received or when
> 3-way handshake has completed. Anyone?

The problem can have many different causes, and I actually think the
device's TCP/IP implementation is quite buggy. But my main concern is: why
can it connect succesfully to any Internet server but not to mine?


Massimo
Author
9 Feb 2007 5:30 PM
Massimo
Show quote
"Massimo" <bar***@mclink.it> ha scritto nel messaggio
news:OClkJJMQHHA.468@TK2MSFTNGP02.phx.gbl...

> This code works perfectly when the client is a .NET program, but crashes
> when a connection is made by the "real" client. A SocketException is
> thrown during the first clientsocket.Receive(), complaining about the
> connection being forcibly closed by the remote host. But the worse is
> still to come: after this error (and the subsequent clientsocket.Close()),
> serversocket.BeginAccept() too throws an exception!
>
> The client, of course, didn't close anything... or at least didn't want
> to. I think there must be some nasty bug in the client's TCP/IP libraries,
> because the server works flawlessly with a .NET client... but, as I said,
> the clients seem to work ok when connecting to other network servers, so
> maybe the problem's here and I'm not correctly handling some error that
> usually doesn't happen but sometimes do.
>
> What can I do to understand what's really happening here?

Turned out it wasn't either the server or the client's fault, but mine :-(

I was using the wrong GPRS APN, and the one I was using could be used only
for WAP connections... so it silently truncated every connection going to a
TCP port different from 80. That was the reason the connection was being
focibly closed as soon as it was established.


Massimo

AddThis Social Bookmark Button