locked
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

    Question

  • I have a c# application (Not Web App) that used TCP/IP Client/Server communication. I am running in to an error that I can't seem to find out the problem. I have a TCP/IP Server class and Client class. I am using Asynchronous calls. The client and server Send Data and Received Data methods are pretty much identical.

    Here is the send data method.

            public void SendData(byte[] Data, MessageType TypeOfMessage)
            {
                try
                {
                    if (m_SendDataLock == null)
                    {
                        m_SendDataLock = new object();
                    }
    
                    lock (m_SendDataLock)
                    {
                        if (m_TcpClient.Connected)
                        {
                            byte[] OriginalData = Data;
    
                            // If the message request is data, then  set
                            // the sending data flag to true;
                            if (TypeOfMessage == MessageType.Data || TypeOfMessage == MessageType.Inform)
                            {
                                m_IsSendingData = true;
                            }
    
                            try
                            {
                                // Generate the specific message being requested
                                byte[] Buffer = Utilities.GenerateMessage(Data, TypeOfMessage, m_EncryptAllData, m_EncryptionAlgorithm);
    
                                //LoggerUtilities.Logger.LogError("Sending from Client: " + Utilities.ConvertByteArrayToString(Buffer), Constants.EVENT_LOG_SOURCE, Constants.EVENT_LOG_NAME, System.Diagnostics.EventLogEntryType.Information);
                               
                                // Write to the stream and flush
                                m_NetworkStream.BeginWrite(Buffer, 0, Buffer.Length, new AsyncCallback(DoneSendingData), m_NetworkStream);
    
                                if (TypeOfMessage == MessageType.Data)
                                {
                                    m_LastDataSentTimestamp = DateTime.Now;
                                    m_LastDataSent = OriginalData;
    
                                    FireDataSentEvent(OriginalData);
    
                                    // Start the timer for the expected ack for the data sent
                                    m_AckWaiter = new Timer();
                                    m_AckWaiter.Interval = 1000;
                                    m_AckWaiter.Elapsed += new ElapsedEventHandler(AckWaiter_Elapsed);
                                    m_AckWaiter.Start();
                                }
                                else if (TypeOfMessage == MessageType.AckData || TypeOfMessage == MessageType.AckHeartbeat)
                                {
                                    FireAckSentEvent(TypeOfMessage);
                                }
                            }
                            #region Catch Blocks
                            catch (Exception Ex)
                            {
                                FireConnectionLostEvent(Ex.Message);
                            }
                            #endregion Catch Blocks
                        }
                        else
                        {
                            FireConnectionLostEvent("Not connected to server.");
                        }
                    }
                }
                catch (Exception Ex)
                {
                    Console.WriteLine("ERROR: " + Ex.Message + Environment.NewLine + Environment.NewLine + Ex.StackTrace);
                }
            }

    Asynchronous callback method when the data is done sending

            private void DoneSendingData(IAsyncResult Ar)
            {
                try
                {
                    m_NetworkStream.EndWrite(Ar);
                    m_NetworkStream.Flush();
                    m_IsSendingData = false;
                }
                catch (Exception Ex)
                {
                    Console.WriteLine("ERROR: " + Ex.Message + Environment.NewLine + Environment.NewLine + Ex.StackTrace);
                }
            }

    And then the Received Data method

            private void ReceiveData(IAsyncResult Ar)
            {
                try
                {
                    AsyncInfo ai = (AsyncInfo)Ar.AsyncState;
    
                    if (m_NetworkStream == null)
                    {
                        m_NetworkStream = ai.Stream;
                    }
    
                    // This will hold the payload data only minus the header information
                    byte[] Payload = null;
    
                    // Holds the total bytes read.
                    int bytesRead = 0;
    
                    try
                    {
                        bytesRead = ai.Stream.EndRead(Ar);
    
                        //LoggerUtilities.Logger.LogError("Client: " + Utilities.ConvertByteArrayToString(ai.Data), Constants.EVENT_LOG_SOURCE, Constants.EVENT_LOG_NAME, System.Diagnostics.EventLogEntryType.Information);
    
    
                        // Store the data into a local variable
                        byte[] dataReceived = ai.Data;
    
                        // Holds the size of the payload.
                        // 1) A integer value
                        // 2) The length of the string tells us how many bytes we used
                        //    to store the size of the payload.
                        string SizeOfPayload = string.Empty;
    
                        // Determine the size of the payload
                        for (int i = 1; i <= dataReceived[0]; i++)
                        {
                            SizeOfPayload += dataReceived[i];
                        }
    
                        // This will have the total bytes we will need to read
                        // in order to get the whol message.
                        int totalBytes = Convert.ToInt32(SizeOfPayload);
    
                        // Initialize the array to the correct size.
                        Payload = new byte[totalBytes];
    
                        // Get the first packet of the data from the message
                        for (int i = 0; i < bytesRead - (SizeOfPayload.ToString().Length + 1); i++)
                        {
                            Payload[i] = dataReceived[i + (SizeOfPayload.ToString().Length + 1)];
                        }
    
                        // If we are expecting more packets, get them
                        while (bytesRead < (totalBytes + (SizeOfPayload.ToString().Length + 1)))
                        {
                            // Determine how many more bytes we need to read to get
                            // the entire message
                            int Difference = totalBytes - (bytesRead - (SizeOfPayload.ToString().Length + 1));
    
    
                            if (Difference > Constants.MAX_BUFFER_SIZE)
                            {
                                bytesRead += ai.Stream.Read(Payload, bytesRead - (SizeOfPayload.ToString().Length + 1), Constants.MAX_BUFFER_SIZE);
    
                            }
                            else
                            {
                                bytesRead += ai.Stream.Read(Payload, bytesRead - (SizeOfPayload.ToString().Length + 1), Difference);
                            }
                        }
                    }
                    #region Catch Blocks
                    catch (ArgumentNullException Ex)
                    {
                        string LineNumber = LoggerUtilities.Logger.GetLineNumber(Ex);
                        string Err = LoggerUtilities.Logger.GenerateErrorMessage(Ex, "TCPIP_Communication_Client", "ReceivedData", LineNumber, "");
                        LoggerUtilities.Logger.LogError(Err, Constants.EVENT_LOG_SOURCE, Constants.EVENT_LOG_NAME, System.Diagnostics.EventLogEntryType.Error);
                        FireConnectionLostEvent(Ex.Message);
                        return;
                    }
                    catch (ArgumentOutOfRangeException Ex)
                    {
                        string LineNumber = LoggerUtilities.Logger.GetLineNumber(Ex);
                        string Err = LoggerUtilities.Logger.GenerateErrorMessage(Ex, "TCPIP_Communication_Client", "ReceivedData", LineNumber, "");
                        LoggerUtilities.Logger.LogError(Err, Constants.EVENT_LOG_SOURCE, Constants.EVENT_LOG_NAME, System.Diagnostics.EventLogEntryType.Error);
    
                        FireConnectionLostEvent(Ex.Message);
                        return;
                    }
                    catch (System.IO.IOException Ex)
                    {
                        string LineNumber = LoggerUtilities.Logger.GetLineNumber(Ex);
                        string Err = LoggerUtilities.Logger.GenerateErrorMessage(Ex, "TCPIP_Communication_Client", "ReceivedData", LineNumber, "");
                        LoggerUtilities.Logger.LogError(Err, Constants.EVENT_LOG_SOURCE, Constants.EVENT_LOG_NAME, System.Diagnostics.EventLogEntryType.Error);
    
                        FireConnectionLostEvent(Ex.Message);
                        return;
                    }
                    catch (ObjectDisposedException Ex)
                    {
                        string LineNumber = LoggerUtilities.Logger.GetLineNumber(Ex);
                        string Err = LoggerUtilities.Logger.GenerateErrorMessage(Ex, "TCPIP_Communication_Client", "ReceivedData", LineNumber, "");
                        LoggerUtilities.Logger.LogError(Err, Constants.EVENT_LOG_SOURCE, Constants.EVENT_LOG_NAME, System.Diagnostics.EventLogEntryType.Error);
    
                        FireConnectionLostEvent(Ex.Message);
                        return;
                    }
                    catch (Exception Ex)
                    {
                        string LineNumber = LoggerUtilities.Logger.GetLineNumber(Ex);
                        string Err = LoggerUtilities.Logger.GenerateErrorMessage(Ex, "TCPIP_Communication_Client", "ReceivedData", LineNumber, "");
                        LoggerUtilities.Logger.LogError(Err, Constants.EVENT_LOG_SOURCE, Constants.EVENT_LOG_NAME, System.Diagnostics.EventLogEntryType.Error);
    
    
                        FireBadDataReceivedEvent(Payload);
                        Array.Clear(m_ReadBuffer, 0, m_ReadBuffer.Length);
                        m_NetworkStream.BeginRead(m_ReadBuffer, 0, m_ReadBuffer.Length, ReceiveData, new AsyncInfo(m_ReadBuffer, m_NetworkStream));
                        return;
                    }
                    #endregion Catch Blocks
    
                    // We should never receive 0 bytes
                    if (bytesRead == 0)
                    {
                        FireBadDataReceivedEvent(Payload);
                        Array.Clear(m_ReadBuffer, 0, m_ReadBuffer.Length);
                        m_NetworkStream.BeginRead(m_ReadBuffer, 0, m_ReadBuffer.Length, ReceiveData, new AsyncInfo(m_ReadBuffer, m_NetworkStream));
                        return;
                    }
    
                    // Get the command
                    //byte Command = Payload[0];
                    MessageType Command = (MessageType)Enum.Parse(typeof(MessageType), Payload[0].ToString());
    
                    // Create a new array to hold everything except the command byte.
                    byte[] SerializedData = new byte[Payload.Length - 1];
    
                    // Copy all the payload except the command byte.
                    Array.Copy(Payload, 1, SerializedData, 0, Payload.Length - 1);
    
                    // TrueData will hold the final payload data after decryption or not.
                    byte[] TrueData;
    
                    // If the flag is set to true, then we need to 
                    // decrypt the data before processing it
                    if (m_EncryptAllData)
                    {
                        TrueData = m_Decryptor.DecryptByteArray(SerializedData, m_EncryptionAlgorithm);
                    }
                    else
                    {
                        TrueData = SerializedData;
                    }
    
                    // Determine what type of message it is by reading the 
                    // first byte of the payload
                    switch (Command)
                    {
                        case MessageType.Heartbeat:                      
                            FireBadDataReceivedEvent(TrueData);
                            break;
                        case MessageType.AckHeartbeat:
                            m_LastAckReceivedTimestamp = DateTime.Now;
                            FireAckReceivedEvent();
    
                            // Reset the heartbeat timeout back to 0
                            m_HeartbeatTimeout = 0;
                            break;
                        case MessageType.Data:
                            m_LastDataReceivedTimestamp = DateTime.Now;
                            m_LastDataReceived = TrueData;
                            FireDataReceivedEvent(TrueData);                        
    
                            // Send and ack for the data received
                            SendData(new Byte[] { }, MessageType.AckData);
                            break;
                        case MessageType.AckData:
                            m_AckWaiter.Stop();
                            m_LastAckReceivedTimestamp = DateTime.Now;
                            FireAckReceivedEvent();
                            m_DataSentCount = 1;
                            //m_IsSendingData = false;
                            break;
                        case MessageType.SubscriberAccountProcessed:
                            FireDataProccessedSuccessfulEvent(TrueData);
                            break;
                        case MessageType.Inform:
                            FireSyncModuleInformationEvent(TrueData);
    
                            // Send and ack for the information received
                            //SendData(new Byte[] { }, MessageType.AckData);
                            break;
                        default:
                            break;
                    }
    
                    // Begin listeneing for data again.
                    m_NetworkStream.BeginRead(m_ReadBuffer, 0, m_ReadBuffer.Length, ReceiveData, new AsyncInfo(m_ReadBuffer, m_NetworkStream));
                }
                #region Catch Blocks
                catch (ObjectDisposedException Ex)
                {
                    string LineNumber = LoggerUtilities.Logger.GetLineNumber(Ex);
                    string Err = LoggerUtilities.Logger.GenerateErrorMessage(Ex, "TCPIP_Communication_Client", "ReceivedData", LineNumber, "");
                    LoggerUtilities.Logger.LogError(Err, Constants.EVENT_LOG_SOURCE, Constants.EVENT_LOG_NAME, System.Diagnostics.EventLogEntryType.Error);
    
                    FireConnectionLostEvent(Ex.Message);
                }
                catch (ArgumentNullException Ex)
                {
                    string LineNumber = LoggerUtilities.Logger.GetLineNumber(Ex);
                    string Err = LoggerUtilities.Logger.GenerateErrorMessage(Ex, "TCPIP_Communication_Client", "ReceivedData", LineNumber, "");
                    LoggerUtilities.Logger.LogError(Err, Constants.EVENT_LOG_SOURCE, Constants.EVENT_LOG_NAME, System.Diagnostics.EventLogEntryType.Error);
    
                    FireConnectionLostEvent(Ex.Message);
                }
                catch (ArgumentOutOfRangeException Ex)
                {
                    string LineNumber = LoggerUtilities.Logger.GetLineNumber(Ex);
                    string Err = LoggerUtilities.Logger.GenerateErrorMessage(Ex, "TCPIP_Communication_Client", "ReceivedData", LineNumber, "");
                    LoggerUtilities.Logger.LogError(Err, Constants.EVENT_LOG_SOURCE, Constants.EVENT_LOG_NAME, System.Diagnostics.EventLogEntryType.Error);
    
                    FireConnectionLostEvent(Ex.Message);
                }
                catch (System.IO.IOException Ex)
                {
                    string LineNumber = LoggerUtilities.Logger.GetLineNumber(Ex);
                    string Err = LoggerUtilities.Logger.GenerateErrorMessage(Ex, "TCPIP_Communication_Client", "ReceivedData", LineNumber, "");
                    LoggerUtilities.Logger.LogError(Err, Constants.EVENT_LOG_SOURCE, Constants.EVENT_LOG_NAME, System.Diagnostics.EventLogEntryType.Error);
    
                    FireConnectionLostEvent(Ex.Message);
                }
                catch (Exception Ex)
                {
                    string LineNumber = LoggerUtilities.Logger.GetLineNumber(Ex);
                    string Err = LoggerUtilities.Logger.GenerateErrorMessage(Ex, "TCPIP_Communication_Client", "ReceivedData", LineNumber, "");
                    LoggerUtilities.Logger.LogError(Err, Constants.EVENT_LOG_SOURCE, Constants.EVENT_LOG_NAME, System.Diagnostics.EventLogEntryType.Error);
    
                    Console.WriteLine("ERROR: " + Ex.Message + Environment.NewLine + Environment.NewLine + Ex.StackTrace);
                }
                #endregion Catch Blocks
            }
    

    Here is the error message I am getting:

    Class: TCPIP_Communication_Server
    Method: ReceivedData
    Message: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
    Line: 294
    Stack Trace:    at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
       at SIS_Communication_Library.TCPIP_Communication_Server.ReceivedData(IAsyncResult Ar) in E:\Alarm Center\SIS\Communication Library\Communication Library\TCPIP_Communication_Server.cs:line 294

    Does anyone see anything that could be causing this problem?

    Thursday, June 28, 2012 2:51 PM

All replies

  • Try using wireshark to trace the connections to help isolate the problem.  It may be the prt number that is wrong, but I don't see the code that is making the connection so I can't tell what port number is being used.

    jdweng

    Thursday, June 28, 2012 4:03 PM
  • Try using wireshark to trace the connections to help isolate the problem.  It may be the prt number that is wrong, but I don't see the code that is making the connection so I can't tell what port number is being used.

    jdweng

    Thanks for the suggestion. Here is a example of the client connecting to the server. I have logs that a connection is made, when I start sending packets of data everything is fine and then out of no where i get the error.

            public void Initialize(string IP, short Port)
            {
                try
                {
                    m_IP = IP;
                    m_Port = Port;
    
                    m_TcpClient = new TcpClient();
                    IPEndPoint ServerEndPoint = new IPEndPoint(IPAddress.Parse(IP), Port);
                    m_TcpClient.Connect(ServerEndPoint);
    
                    FireConnectionEstablishedEvent();                
    
                    m_NetworkStream = m_TcpClient.GetStream();
                    m_NetworkStream.BeginRead(m_ReadBuffer, 0, m_ReadBuffer.Length, ReceiveData, new AsyncInfo(m_ReadBuffer, m_NetworkStream));
    
                    m_HeartbeatTimer = new Timer();
                    m_HeartbeatTimer.Elapsed += new ElapsedEventHandler(HeartbeatTimer_Tick);
                    m_HeartbeatTimer.Interval = HeartbeatSettings.HeartbeatTiming.IntervalCount * 1000;
                    m_HeartbeatTimer.Start();
    
                    m_ReconnectToServer = new Timer();
                    m_ReconnectToServer.Elapsed += new ElapsedEventHandler(ReconnectToServer_Elapsed);
                    m_ReconnectToServer.Interval = 5000;
                }
                #region Catch Blocks
                catch (ArgumentOutOfRangeException Ex)
                {
                    FireConnectionFailedEvent();                
                }
                catch (ArgumentNullException Ex)
                {
                    FireConnectionFailedEvent(); 
                }
                catch (System.Net.Sockets.SocketException Ex)
                {
                    FireConnectionFailedEvent(); 
                }
                catch (ObjectDisposedException Ex)
                {
                    FireConnectionFailedEvent(); 
                }
                catch (System.IO.IOException Ex)
                {
                    FireConnectionFailedEvent(); 
                }
                #endregion Catch Blocks
            }

    Thursday, June 28, 2012 4:45 PM
  • There is a differrence between a client and server how the connection is made.  The sdrver and client should both use a TCPClient for the socket connection

    1)  The server should come up first and connect to the local IP address.

    2) the client should come up 2nd and connect to the server IP address.

    The code you posted looks like a server code because the connection is to the endpoint.


    jdweng

    Thursday, June 28, 2012 6:24 PM
  • There is a differrence between a client and server how the connection is made.  The sdrver and client should both use a TCPClient for the socket connection

    1)  The server should come up first and connect to the local IP address.

    2) the client should come up 2nd and connect to the server IP address.

    The code you posted looks like a server code because the connection is to the endpoint.


    jdweng

    Nope, this is my Server Initialize method:

            public void Initialize(string IP, int Port)
            {
                try
                {
                    IPAddress Address = IPAddress.Parse(IP);
                    m_Listener = new TcpListener(Address, Port);
                    m_Listener.Start();
                    m_Listener.BeginAcceptTcpClient(ConnectionRequested, null);
                }
                catch (Exception Ex)
                {
                    Console.WriteLine("ERROR: " + Ex.Message + Environment.NewLine + Environment.NewLine + Ex.StackTrace);
                }
            }


    And this is the callback method once a Client tries to connect

            /// <summary>
            /// Handles the asynchronous BeginAcceptTcpClient 
            /// method of the TCPListener object.
            /// </summary>
            /// <param name="Ar">Result of the asyncronous call</param>
            private void ConnectionRequested(IAsyncResult Ar)
            {
                try
                {
                    if (m_Listener != null)
                    {
                        m_TcpClient = m_Listener.EndAcceptTcpClient(Ar);
                    }
    
                    if (m_TcpClient != null)
                    {
                        if (m_TcpClient.Connected)
                        {
                            FireConnectionEstablishedEvent();
    
                            m_NetworkStream = m_TcpClient.GetStream();
                            Array.Clear(m_ReadBuffer, 0, m_ReadBuffer.Length);
                            m_NetworkStream.BeginRead(m_ReadBuffer, 0, m_ReadBuffer.Length, ReceivedData, new AsyncInfo(m_ReadBuffer, m_NetworkStream));
    
                            m_CheckForNoHeartbeatsFromClient.Enabled = false;
                            m_CheckForNoHeartbeatsFromClient.Interval = this.m_HeartbeatSettings.HeartbeatTiming.IntervalCount * 1000;
                            m_CheckForNoHeartbeatsFromClient.Elapsed += new ElapsedEventHandler(CheckForNoHeartbeatsFromClient_Elapsed);
    
                        }
                    }
                }
                catch (Exception Ex)
                {
                    FireErroredEvent(Ex);
                }
            }

    • Edited by brown71576 Thursday, June 28, 2012 6:41 PM
    Thursday, June 28, 2012 6:39 PM
  • Canyou specify what IP address are being used.  the Server look like it is correct, but the client I think is wrong.  the client shouldn't be using an endpoint, instead the client should connect to the server IP address.

    jdweng

    Thursday, June 28, 2012 8:58 PM
  • Canyou specify what IP address are being used.  the Server look like it is correct, but the client I think is wrong.  the client shouldn't be using an endpoint, instead the client should connect to the server IP address.

    jdweng

    The server is just a listener on a specified port of 1000. The Server is a local machine with a IP 192.168.1.241. The Client connects to that IP and Port 1000
    Thursday, June 28, 2012 9:27 PM
  • Still can't find out this problem. Anyone else have any ideas?
    Thursday, July 05, 2012 4:53 PM
  • 1) Have you put break point in the server code to see if the connection is established

    2) Have you traced the connections using wireshark?

    At this point of time we don't know if the problem is in the client of the server.  You can alway do the following from the client

    1) Launch Start - All Programs Accessories - Communications - Hyperterminal

    2) Enter any name in the first pop up and press OK

    3) Select in the Connect Using box the following : TCP/IP (winsock)

    4) Enter Host IP address and Port number of server.  Yo ucan actauly do this from either the client of the server, but make sure you put the server IP address

    5) Check the status in the lower left corner of the hyper-terminal.  If the server code is correct you will connect, otherwise after 30 seconds you will get a timeout.

    6) You can run the hyperterminal while visual Studio is running and with break points in the code.  You cna also send commands to the server by typing the commands in the hyperterminal window.

    7) You can also ping the server from th eclient to make sure you have a route from the client to the server.


    jdweng

    Thursday, July 05, 2012 5:11 PM
  • 1) Have you put break point in the server code to see if the connection is established - YES

    2) Have you traced the connections using wireshark? YES - Could not make out anything. Maybe lack of understanding Wireshark.

    I will try your other suggestions. Thanks
    Thursday, July 05, 2012 6:17 PM
  • There are a lot of fine details in the wireshark trace that is important in isolating the problem.  there are messages like [SYNC ACK] which indicated the connection completed and [FIN ACK] which indicates the connection is closing.  Also the sequence numbers port numbers, message length, retries can be very useful.  With TCP every mesage get an ACK.  When no ACK is sent or multiple ACK are sent it indicates a problem.

    jdweng

    Thursday, July 05, 2012 8:15 PM