|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Strange server socket behaviourThis 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 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 -- Show quoteHTH, Kevin Spencer Microsoft MVP Software Composer http://unclechutney.blogspot.com The shortest distance between 2 points is a curve. "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 > "Kevin Spencer" <unclechut***@nothinks.com> ha scritto nel messaggio I'm sorry?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 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 Massimo wrote:
> Why should the remote client close the connection? Its C code isn't telling I think you need to break out a packet analyser like Wireshark or> 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. similar, and see what's going on over the wires. -- Barry Barry Kelly wrote:
Show quote > Massimo wrote: Yes, packet analyzer should do the trick (Ethereal is also good). I > >> 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 > 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 "Goran Sliskovic" <gslis***@yahoo.com> ha scritto nel messaggio Can you elaborate about this, or give me some links to more info?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. Massimo "Massimo" <bar***@mclink.it> wrote in message It's just a thought... I suppuse you receive RST segment, becuase error isnews: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 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 "Goran Sliskovic" <gslis***@yahoo.com> ha scritto nel messaggio The problem is, the client isn't doing any Close() at all!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. 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
Show quote
"Massimo" <bar***@mclink.it> wrote in message Is that some kind of routed network/dialup?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 :-( .... Goran "Goran Sliskovic" <gslis***@yahoo.com> ha scritto nel messaggio See the original post for details.news:%23LNllweRHHA.1200@TK2MSFTNGP02.phx.gbl... > Is that some kind of routed network/dialup? Massimo "Massimo" <bar***@mclink.it> wrote in message Ah, sorry, it was few days ago. It's hard to tell without the actual packetnews: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. .... 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
Show quote
"Goran Sliskovic" <gslis***@yahoo.com> ha scritto nel messaggio The problem can have many different causes, and I actually think the 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? 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
Show quote
"Massimo" <bar***@mclink.it> ha scritto nel messaggio Turned out it wasn't either the server or the client's fault, but mine :-(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? 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 |
|||||||||||||||||||||||