TCP connection forcibly closed by ShipModul's Miniplex-3Wi - c#

We have been developing a .NET Framework 4.6.1 app with C# that has as one of its tasks to send NMEA 0183 sentences to a multiplexer via local area network connection (Wi-Fi or Ethernet). The app can be configured to connect using TCP or UDP. The communication between the app and the multiplexer works over UDP for hours without any problems, but TCP connection has this problem that a ShipModul's multiplexer that I have been using in my own testing scenarios forcibly closes the connection after about 10 or 15 minutes. Also, other users of the app have confirmed that other multiplexers might not work at all when the app is configured to use TCP, but that UDP connection still works without a problem. The communication is one-way from the .NET Framework app to multiplexer.
What might be the reason for the premature closing of the TCP connection? Is there some requirement and mechanism to actively keep the connection alive, and not just that it is assumed to be alive when IP packets arrive from the PC? And if the connection needs to be actively maintained, then how you do it with .NET TcpClient object?
Simplyt put, the code is something like (executed only when using TCP):
// connection initilization
tcpClient = new TcpClient(new IPEndPoint(unicastAddress.Address, port));
tcpClient.Connect(ipAddress, port);
networkStream = tcpClient.GetStream();
// ..prepare the NMEA sentence data..
networkStream.Write(asciiEncodedNmeaData, 0, asciiEncodedNmeaData.Length);
The corresponding UDP protocol version of the code (executed only when using UDP):
// connection initialization
udpClient = new UdpClient(new IPEndPoint(unicastAddress.Address, port));
udpClient.Connect(ipAddress, port);
// ..prepare the NMEA sentence data..
udpClient.Send(asciiEncodedNmeaData, asciiEncodedNmeaData.Length);
Also, when the app is closed/paused, the Close() method is called on either of the above client object depending on which protocol is used (and everything restarts as above when the app is unpaused):
tcpClient.Close();
networkStream.Close();
or:
udpClient.Close();
Then, after about 15 minutes there appears this exception:
System.IO.IOException: 'Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.'

It's a standard situation. TCP connection is stateful, i.e. consumes finite resources like memory. That's why network equipment usually discards inactive connections. In your case connection is considered idle "after about 10 or 15 minutes".
To avoid this, you can send "keep alive packets". Just write any data (the less the better) to networkStream by timer, e.g. every 5 minutes.

Related

C# Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. Reading networkstream

I have looked at
unable to read data from the transport connection the connection was closed
Unable to read data from the transport connection : An existing connection was forcibly closed by the remote host
Unable to read data from the transport connections
I am new to this and I have been told the issue is not the server. Is there anyway the issue can be client side or the client is causing an issue that forces the server to disconnect?
I make my connection
_client.BeginConnect(host, port, ConnectCallback, null);
and then in ConnectCallback
_client.EndConnect(result);`
_client.NoDelay = true;`
_client.ReceiveBufferSize = 65535;`
NetworkStream ns = _client.GetStream();`
byte[] buffer = new byte[_client.ReceiveBufferSize];`
ns.BeginRead(buffer, 0, buffer.Length, ReadCallback, buffer);`
and then in ReadCallback
ns = _client.GetStream();`
read = ns.EndRead(result);`
Which is where it sometimes fails. There are other connections in the app and they have no problems. One of the connections is to the same server that I am having issues, but on a different port.
All the machines are on the same network. This is the only client connecting to this particular server/port. We run the app for about 3 hours and this error happens anytime.
Edit
I appreciate the comments and input. Being new to programming and networking, etc, I still have the question: Is it possible the client is causing the issue?
The remote endpoint or a device on the network is closing the TCP connection.
You always need to test that the TCP connection is available and connected before reading from it.
You have no control over when the remote endpoint closes the connection. Even if you wrote the code on the remote endpoint it could still close due to a power outage.
The ReadCallback will be fired when the connection is closed, as well as when data is available. Your code is responsible for detecting that the connection has been closed and taking the necessary action in your code to deal with this scenario.
The easiest way to deal with this is to catch the exception, stop reading/writing from/to the socket, do any clean up tasks and reconnect if necessary etc etc..

What could be causing a delay in TCP ACK in my app

I have a .NET windows service that uses an open source library (Asterisk.net - C#) to listen to TCP connections on a specific port.
This service is deployed on a number of VM instances of Windows 7 (all from the same source image). The connections all come from the VM host (centos). On one (and only one) of these instances the ACK response from windows to the connecting client is delayed by three seconds on the occasional incoming connection. Other times, the ACK is sent immediately.
This delay causes the client to time out:
I'm no expert at TCP sockets, but it seems from a debug that these ACKs are sent before the connection is handed to the app (or in this case library), and even if the accepting thread is blocked, so it is a problem at the windows or .net library level?
The code that handles the inbound connections quickly hands it off to a thread and returns.
public IO.SocketConnection Accept()
{
if (tcpListener != null)
{
TcpClient tcpClient = tcpListener.AcceptTcpClient();
if (tcpClient != null)
return new IO.SocketConnection(tcpClient, encoding);
}
return null;
}
So, what could be causing this infuriating delay? What am I missing?
These 3 packets you recorded are the establishing of the connection. See https://en.m.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_establishment.
However, if it happens only in 1 VM, then it's no programming issue. Try loading the VMs in different order, check firewall settings etc.
Also, test with a network terminal software like HWGroup Hercules and monitor the connections using Sysinternals TCPView.

What are the possible reasons of SocketError.ConnectionReset in TCP Socket

I have a TCP socket based client server system.
Everything works fine but when network is disconnected form client end and reconnect it again i get automatically SocketError.ConnectionReset send form client and regarding this command the socket is closed in the server side. this is also fine.
but when i look in to the client side it shows the socket is still connected with server. (regarding socket is still connected with server [It does not happen every time], sometime it shows disconnected and some times shows connected)
Does it make sense that "server get a SocketError.ConnectionReset from
client end but client is still connected"?
So i want to know what is the possible reasons of SocketError.ConnectionReset and how to handle such type of problem i have mentioned?
Again i say, Everything is working fine in normal environment (e.g if i exit the client it is disconnected the socket same for the server)
Thanks in advance.
EDIT:
Here is the code in the client side. actually it's a timer that tick every 3 second through programs lifetime and check if Socket is connected or not if its disconnected then it tries to reconnect again through a new socket instance
private void timerSocket_Tick(object sender, EventArgs e)
{
try
{
if (sck == null || !sck.Connected)
{
ConnectToServer();
}
}
catch (Exception ex)
{
RPLog.WriteDebugLog("Exception occcured at: "+ System.Reflection.MethodBase.GetCurrentMethod().ToString()+"Message: "+ex.Message);
}
}
In normal situation (without network disconnect/reconnect) if TCP server get a
SocketError.ConnectionReset form any client, in the client side i see
clients socket is disconnected and it tries to reconnect it again
through the code shown. but when situation happen explained earlier,
server gets a SocketError.ConnectionReset but client shows it still
connected. though the TCP server shows the reset command is send form the exact client
side.
There are several causes but the most common is that you have written to a connection that has already been closed but he other end. In other words, an application protocol error. When it happens you have no choice but to close the socket, it is dead. However you can fix the underlying cause.
When discussing a TCP/IP issue like this, you must mention the network details between the client and the server.
When one side says the connection is reset, it simply means that on the wire a RST packet appears. But to know who sends the RST packet and why, you must utilize network packet captures (by using Wireshark and any other similar tools),
https://en.wikipedia.org/wiki/Transmission_Control_Protocol
You won't easily find out the cause at .NET Framework level.
The problem with using Socket.Connected as you are is that it only gives you the connected state as at the last Send or Receive operation. i.e. It will not tell you that the socket has disconnected unless you first try to send some data to it or receive data from it.
From MSDN description of the Socket.Connected property:
Gets a value that indicates whether a Socket is connected to a remote host as of the last Send or Receive operation.
So in your example, if the socket was functioning correctly when you last sent or received any data from it, the timerSocket_Tick() method would never call ConnectToServer(), even if the socket was now not connected.
how to handle such type of problem i have mentioned?
Close the socket and initiate a new connection.

Closing System.Net.Sockets.TcpClient kills the connection for other TCPClients at the same IP Address

Just to be clear, all of the TCPClients I'm referring to here are not instances of my own class, they are all instances of System.Net.Sockets.TcpClient from Mono's implementation of .NET 4.0.
I have a server that is listening for client connections, as servers do. Whenever it gets a new client it creates a new TCPClient to handle the connection on a new thread. I'm keeping track of all the connections and threads with a dictionary. If the client disconnects, it sends a disconnect message to the server, the TCPClient is closed, the dictionary entry is removed and the thread dies a natural death. No fuss, no muss. The server can handle multiple clients with no problem.
However, I'm simulating what happens if the client gets disconnected, doesn't have a chance to send a disconnect message, then reconnects. I'm detecting whether a client has reconnected with a username system (it'll be more secure when I'm done testing). If I just make a new TCPClient and leave the old one running, the system works just fine, but then I have a bunch of useless threads lying around taking up space and doing nothing. Slackers.
So I try to close the TCPClient associated with the old connection. When I do that, the new TCPClient also dies and the client program throws this error:
E/mono (12944): Unhandled Exception: System.IO.IOException: Write failure ---> System.Net.Sockets.SocketException: The socket has been shut down
And the server throws this error:
Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.
Cannot read from a closed TextReader.
So closing the old TCPClient with a remote endpoint of say: 192.168.1.10:50001
Also breaks the new TCPClient with a remote endpoint of say:192.168.1.10:50002
So the two TCPClient objects have the same remote endpoint IP address, but different remote endpoint ports. But closing the one seems to stop the other from working. I want to be able to close the old TCPClient to do my cleanup, without closing the new TCPClient.
I suspect this is something to do with how TCPClient works with sockets at a low level, but not having any real understanding of that, I'm not in a position to fix it.
I had a similar issue on my socket server. I used a simple List instead of a dictionary to hold all of my current connections. In a continuous while loop that listens for new streams, I have a try / catch and in the catch block it kills the client if it has disconnected.
Something like this on the sever.cs:
public static void CloseClient(SocketClient whichClient)
{
ClientList.Remove(whichClient);
whichClient.Client.Close();
// dispose of the client object
whichClient.Dispose();
whichClient = null;
}
and then a simple dispose method on the client:
public void Dispose()
{
System.GC.SuppressFinalize(this);
}
EDIT: this paste is the OPs resolution which he or she found on their own with help from my code.
So to clarify, the situation is that I have two TCPClient objects TCPClientA and TCPClientB with different remote endpoints ports, but the same IP:
TCPClientA.Client.RemoteEndPoint.ToString();
returns: 192.168.1.10:50001
TCPClientB.Client.RemoteEndPoint.ToString();
returns: 192.168.1.10:50002
TCPClientA needs to be cleaned up because it's no longer useful, so I call
TCPClientA.Close();
But this closes the socket for the client at the other end of TCPClientB, for some reason. However, writing
TCPClientA.Client.Close();
TCPClientA.Close();
Successfully closes TCPClientA without interfering with TCPClientB. So I've fixed the problem, but I don't understand why it works that way.
Looks like you have found a solution but just so you are aware there are many similar pitfalls when writing client/server applications in .net. There is an open source network library (which is fully supported in mono) where these problems have already been solved, networkComms.net. A basic sample is here.
Disclaimer: This is a commercial product and I am the founder.
This is clearly an error in your code. Merely closing one inbound connection cannot possibly close another one. Clearly something else is happening elsewhere in your code.

How to test a remote UDP Port

I am looking for a simple way to see if a remote UDP port is open on a server
BEWARE that several firewalls/network setups/IDS etc. might influence the result... the following method is NOT 100% reliable but it is the only method possible with UDP IMHO (since UDP is connectionless).
You can use UdpClient, set a receive timeout on the underlying socket, make a connection to that remote server/port, Send some small message (byte[] !) and call Receive.
IF the port is closed you get an exception saying that the connection was forcibly closed (SocketException with ErrorCode 10054 = WSAECONNRESET)... which means the port is NOT open.
Otherwise you either receive an answer OR a timeout exception - both should be interpreted as "the UDP port is open".
You can not. That is by design because UDP is connectionless. You have to solve that on application layer.

Categories

Resources