473,405 Members | 2,287 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

TCP Connection Timeout

Airslash
221 100+
Hello,

I've written my own TCPClient and TCPServer class components to handle traffic over the network between applications.
When I test the components locally they work. In the local network between different machines they also work.

When I try to connect to a remote location that's added to our network with Tunnels, I'm receiving a Timeout on the connect, but a ping to the IP from commandline works fine without a problem.

There's a firewall between the 2 locations, but the ports used during the connection have been opened. Yet the timeout keeps occuring. Is there anything special I need to do ?

Client Code:
Expand|Select|Wrap|Line Numbers
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Net.Sockets;
  8. using System.Text;
  9. using System.Threading;
  10.  
  11. /* Components API */
  12. using Components;
  13. using Components.EventArgs;
  14.  
  15. namespace Components.Network.Clients
  16. {
  17.     /// <summary>
  18.     /// This class is a direct implementation of the IClient interface and provides a concrete
  19.     /// implementation using the TCP protocol and Berkley sockets as it's base components.
  20.     /// </summary>
  21.     public class TCPClient : IClient
  22.     {
  23.         #region Constructors
  24.  
  25.         /// <summary>
  26.         /// Creates a new instance of the TCPClient class and initializes the internal components
  27.         /// of the class to be ready for establishing a connection to a remote location.
  28.         /// The client is considered 'disconnected' and is not actively listening for data.
  29.         /// </summary>
  30.         /// <param name="address">The remote ip address to establish a connection with.</param>
  31.         /// <param name="port">The remote port to establish a connection with.</param>
  32.         public TCPClient(string remoteAddress, int remotePort)
  33.         { 
  34.             // Save the parameters into the local fields and initialize the internal
  35.             // members of our class.
  36.             m_lock = new object();
  37.             m_socket = null;
  38.             m_backgroundthread = null;
  39.             m_running = false;
  40.             m_local_endpoint = new IPEndPoint(IPAddress.Any, 0);
  41.             m_remote_endpoint = new IPEndPoint(IPAddress.Loopback, 0);
  42.             RemoteAddress = remoteAddress;
  43.             RemotePort = remotePort;
  44.             Asynchronous = true;
  45.             Connected = false;
  46.         }
  47.  
  48.         /// <summary>
  49.         /// Creates a new instance of the TCPClient class with the socket that has been accepted by
  50.         /// an IServer implementation. The client assumes the socket to be following the TCP protocol,
  51.         /// but will not validate this.
  52.         /// The internal components of the TCPClient are automaticly configured and the client is considered
  53.         /// 'connected' and will handle incoming data.
  54.         /// </summary>
  55.         /// <param name="socket">The Socket accepted by the IServer implementation.</param>
  56.         public TCPClient(Socket socket)
  57.         { 
  58.             // Save the parameters into the local datamembers and extract
  59.             // the required information from the socket.
  60.             m_lock = new object();
  61.             m_backgroundthread = null;
  62.             Asynchronous = true;
  63.             m_socket = socket;
  64.             m_socket.NoDelay = true;
  65.             m_local_endpoint = (socket.LocalEndPoint as IPEndPoint);
  66.             m_remote_endpoint = (socket.RemoteEndPoint as IPEndPoint);
  67.             Connected = socket.Connected;
  68.  
  69.             // Initialize the internal background thread, because we assume the socket
  70.             // to be connected.
  71.             InitializeBackgroundThread();
  72.         }
  73.  
  74.         #endregion
  75.  
  76.         #region Public Methods
  77.  
  78.         /// <summary>
  79.         /// Determines if two IClient objects are equall. IClient objects are considered
  80.         /// equal if they connect to the same endpoint.
  81.         /// </summary>
  82.         /// <param name="other">The other IClient to compare against.</param>
  83.         /// <returns>True if both IClients are considered equall.</returns>
  84.         public bool Equals(IClient other)
  85.         {
  86.             return string.Equals(this.RemoteAddress, other.RemoteAddress) && (this.RemotePort == other.RemotePort);
  87.         }
  88.  
  89.         /// <summary>
  90.         /// Establishes a connection to a remote location and initializes the internal
  91.         /// components to process incomming data.
  92.         /// </summary>
  93.         /// <returns>The reference to the IClient implementation.</returns>
  94.         /// <remarks>If the connection attempt succeeds, the Connected property will be set to true; otherwise false.</remarks>
  95.         public IClient Connect()
  96.         {
  97.             // Claim the lock on the socket, so we have exclusive access to the socket during the
  98.             // connection attempt.
  99.             lock (m_lock)
  100.             {
  101.                 // Check if the socket is already connected. If a connection has already been 
  102.                 // established, do not try to connect again.
  103.                 if (!Connected)
  104.                 {
  105.                     // Surround the entire connection attempt with a try-catch statement to prevent
  106.                     // errors from breaking the code.
  107.                     try
  108.                     {
  109.                         // Create a new instance of the Berkley socket that relies on the InterNetwork for
  110.                         // IPv4 connections and uses the TCP Streaming protocol for communication.
  111.                         m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  112.  
  113.  
  114.                         // Bind the socket to the local endpoint specified. Depending on the settings made by the 
  115.                         // user this is a specific ip and port or a random selection by the OS.
  116.                         m_socket.Bind(m_local_endpoint);
  117.  
  118.                         // Establish a connection to the remote endpoint. This is determined by the settings
  119.                         // made by the user.
  120.                         m_socket.Connect(m_remote_endpoint);
  121.  
  122.                         // Configure the socket to ignore the Naggle algorithm when sending data.
  123.                         m_socket.NoDelay = true;
  124.  
  125.                         // Initialize the background thread to properly handle incoming data from the socket.
  126.                         InitializeBackgroundThread();
  127.  
  128.                         // Set the Connected flag to true.
  129.                         Connected = true;
  130.  
  131.                         // Raise the onConnected event.
  132.                         RaiseOnConnectEvent(RemoteAddress, RemotePort);
  133.  
  134.                     }
  135.                     catch (Exception ex)
  136.                     {
  137.                         // Raise the onError event first.
  138.                         RaiseOnErrorEvent("Connect", ex);
  139.  
  140.                         // Call the disconnect routine.
  141.                         Disconnect();
  142.                     }
  143.                 }
  144.             }
  145.  
  146.             // Return the reference to ourselves so we can link function calls.
  147.             return this;
  148.         }
  149.  
  150.         /// <summary>
  151.         /// Terminates the connection with a remote location and uninitializes the internal
  152.         /// components that process incoming data.
  153.         /// </summary>
  154.         /// <remarks>The connected property is always set to false regardless of the success of the function.</remarks>
  155.         public IClient Disconnect()
  156.         {
  157.             // Obtain the lock so we have exlusive access to the entire socket while performing this operation.
  158.             lock (m_lock)
  159.             {
  160.                 // Surround the entire disconnect operation with a try-catch statement. This prevents errors from
  161.                 // breaking the code.
  162.                 try
  163.                 {
  164.                     // Check if the socket is connected. If the socket is not connected, then we
  165.                     // don't have to do anything.
  166.                     if (Connected)
  167.                     {
  168.                         // First we'll stop the background thread in a proper fashion.
  169.                         UninitializeBackgroundThread();
  170.  
  171.                         // Close the connection of the socket, but make sure we don't dispose the
  172.                         // internal data of the socket. We only wish to terminate the connection
  173.                         // so that the socket can be reused at a later point.
  174.                         m_socket.Shutdown(SocketShutdown.Both);
  175.                         m_socket.Close();
  176.                         m_socket = null;
  177.  
  178.                         // Raise the OnDisconnected event.
  179.                         RaiseOnDisconnectEvent(RemoteAddress, RemotePort);
  180.                     }
  181.  
  182.                     // Always set the connected flag back to false.
  183.                     Connected = false;
  184.                 }
  185.                 catch (Exception ex)
  186.                 {
  187.                     // Raise the onError event with the given exception.
  188.                     RaiseOnErrorEvent("Disconnect", ex);
  189.                 }
  190.  
  191.                 // Always set the connected property to false.
  192.                 Connected = false;
  193.             }
  194.  
  195.             // Return a reference to ourselves so we link calls.
  196.             return this;
  197.         }
  198.  
  199.         /// <summary>
  200.         /// Sends the data stored in the array over the socket to the remote endpoint. The function reports
  201.         /// back the amount of bytes that have been send over the socket.
  202.         /// </summary>
  203.         /// <param name="data">A one-dimensional array holding the data to be sent.</param>
  204.         /// <param name="length">The amount of bytes to send, starting at the first position in the array.</param>
  205.         /// <returns>The amount of bytes that have been sent over the socket.</returns>
  206.         /// <remarks>The function will return -1 if an error occurs and returns zero if no connection was available.</remarks>
  207.         public int Send(byte[] data, int length)
  208.         {
  209.             // Obtain the lock on the socket, so we have exclusive access to the socket
  210.             // while performing the send operation.
  211.             lock (m_lock)
  212.             {
  213.                 // Check if the connection is available. Return the amount of bytes beeing sent,
  214.                 // or return -1 in case of an error, or 0 in case of no connection.
  215.                 if (Connected)
  216.                     try { return m_socket.Send(data, length, SocketFlags.None); }
  217.                     catch (Exception ex) { RaiseOnErrorEvent("Send", ex); return -1; }
  218.                 else return 0;
  219.             }
  220.         }
  221.  
  222.         #endregion
  223.  
  224.         #region Public Properties
  225.  
  226.         /// <summary>
  227.         /// Gets or sets the remote IP address of the connection.
  228.         /// </summary>
  229.         /// <exception cref="ArgumentException">The provided value cannot be cast into a valid IP address.</exception>
  230.         public string RemoteAddress
  231.         {
  232.             get { return m_remote_endpoint.Address.ToString(); }
  233.             set
  234.             {
  235.                 IPAddress address;
  236.                 if (IPAddress.TryParse(value, out address)) m_remote_endpoint.Address = address;
  237.                 else throw new ArgumentException("The provided value cannot be cast into a valid IP address.");
  238.             }
  239.         }
  240.  
  241.         /// <summary>
  242.         /// Gets or sets the local IP address of the connection.
  243.         /// </summary>
  244.         /// <exception cref="ArgumentException">The provided value cannot be cast into a valid IP address.</exception>
  245.         public string LocalAddress
  246.         {
  247.             get { return m_local_endpoint.Address.ToString(); }
  248.             set
  249.             {
  250.                 IPAddress address;
  251.                 if (IPAddress.TryParse(value, out address)) m_local_endpoint.Address = address;
  252.                 else throw new ArgumentException("The provided value cannot be cast into a valid IP address.");
  253.             }
  254.         }
  255.  
  256.         /// <summary>
  257.         /// Gets or sets the remote port of the connection.
  258.         /// </summary>
  259.         /// <exception cref="ArgumentException">The provided value is not a valid port.</exception>
  260.         /// <remarks>Valid ports are any integer between 1 and 65535.</remarks>
  261.         public int RemotePort
  262.         {
  263.             get { return m_remote_endpoint.Port; }
  264.             set
  265.             {
  266.                 if ((value < 1) || (value > ushort.MaxValue)) throw new ArgumentException("The provided value is not a valid port.");
  267.                 else m_remote_endpoint.Port = value;
  268.             }
  269.         }
  270.  
  271.         /// <summary>
  272.         /// Gets or sets the local port of the connection.
  273.         /// </summary>
  274.         /// <exception cref="ArgumentException">The provided value is not a valid port.</exception>
  275.         /// <remarks>Valid ports are any integer between 1 and 65535.</remarks>
  276.         public int LocalPort
  277.         {
  278.             get { return m_local_endpoint.Port; }
  279.             set 
  280.             {
  281.                 if ((value < 1) || (value > ushort.MaxValue)) throw new ArgumentException("The provided value is not a valid port.");
  282.                 else m_local_endpoint.Port = value; 
  283.             }
  284.         }
  285.  
  286.         /// <summary>
  287.         /// Gets a value indicating whether the IClient is connected.
  288.         /// </summary>
  289.         public bool Connected
  290.         {
  291.             get { return m_connected; }
  292.             protected set { m_connected = value; }
  293.         }
  294.  
  295.         /// <summary>
  296.         /// Gets or sets a value indicating whether the events are fired asynchronous or not.
  297.         /// </summary>
  298.         /// <remarks>Asynchronous and Synchronous events are both raised in sequence, but Asynchronous Events do not wait for the previous event to finish.</remarks>
  299.         public bool Asynchronous
  300.         {
  301.             get { return m_asynchronous; }
  302.             set { m_asynchronous = value; }
  303.         }
  304.  
  305.         #endregion
  306.  
  307.         #region Events
  308.  
  309.         /// <summary>
  310.         /// This event gets raised when the IClient implementation receives data on
  311.         /// the internal socket.
  312.         /// </summary>
  313.         public event EventHandler<DiagramArguments> OnData
  314.         {
  315.             add { m_event_data += value; }
  316.             remove { m_event_data -= value; }
  317.         }
  318.  
  319.         /// <summary>
  320.         /// This event gets raised when the IClient implementation establishes
  321.         /// a connection to a remote endpoint.
  322.         /// </summary>
  323.         public event EventHandler<ConnectionArguments> OnConnect
  324.         {
  325.             add { m_event_connect += value; }
  326.             remove { m_event_connect -= value; }
  327.         }
  328.  
  329.         /// <summary>
  330.         /// This event gets raised when the IClient implementation terminates
  331.         /// a connection from a remote endpoint.
  332.         /// </summary>
  333.         public event EventHandler<ConnectionArguments> OnDisconnect
  334.         {
  335.             add { m_event_disconnect += value; }
  336.             remove { m_event_disconnect -= value; }
  337.         }
  338.  
  339.         /// <summary>
  340.         /// This event gets raised when the IClient implementation encounters an internal
  341.         /// error during the execution of the functionality calls.
  342.         /// </summary>
  343.         public event EventHandler<ErrorArguments> OnError
  344.         {
  345.             add { m_event_error += value; }
  346.             remove { m_event_error -= value; }
  347.         }
  348.  
  349.         #endregion
  350.  
  351.         #region Private Methods
  352.  
  353.         /// <summary>
  354.         /// Initializes the internal background thread of the IClient implementation. The thread
  355.         /// polls the socket for incoming data and raises the onData event when the connection is
  356.         /// established.
  357.         /// </summary>
  358.         /// <returns>True if the background thread is properly initialized; otherwise false.</returns>
  359.         protected virtual bool InitializeBackgroundThread()
  360.         {
  361.             // Surround the entire initialization procedure with a try-catch statement
  362.             // to trace errors in the code and to prevent these errors from breaking
  363.             // the calling code.
  364.             try
  365.             {
  366.                 // Create a new instance of the Thread class and configure the instance to
  367.                 // work with our internal listen routine.
  368.                 m_backgroundthread = new Thread(new ThreadStart(ListenRoutine));
  369.  
  370.                 // Configure the thread to work as a background thread, and to run
  371.                 // independently from the application.
  372.                 m_backgroundthread.IsBackground = true;
  373.                 m_backgroundthread.Name = string.Format("<TCPClient:{0}:{1}:ListenThread>", LocalAddress, LocalPort);
  374.                 m_backgroundthread.Start();
  375.  
  376.                 // Return true since the thread has been properly initialized.
  377.                 return true;
  378.             }
  379.             catch (Exception ex)
  380.             {
  381.                 // Raise the onError event with the given exception.
  382.                 RaiseOnErrorEvent("InitializeBackgroundThread", ex);
  383.  
  384.                 // Return false since we could not properly initialize
  385.                 // the background thread.
  386.                 return false;
  387.             }
  388.         }
  389.  
  390.         /// <summary>
  391.         /// Stops the internal background thread in a proper fashion, allowing the thread
  392.         /// to finish it's last cycle over the internal socket if possible and then gracefully
  393.         /// exiting the loop.
  394.         /// </summary>
  395.         protected virtual void UninitializeBackgroundThread()
  396.         {
  397.             // Stop the background thread by setting the running flag back to
  398.             // false.
  399.             m_running = false;
  400.  
  401.             // Nullify the reference to the background thread.
  402.             m_backgroundthread = null;
  403.         }
  404.  
  405.         /// <summary>
  406.         /// This function is ran from the internal background thread of the IClient implementation
  407.         /// and has the responsebility of polling the underlying socket for incoming data.
  408.         /// If there is data available on the socket, the function will read the entire data into
  409.         /// a single buffer and raise the onData event.
  410.         /// </summary>
  411.         protected virtual void ListenRoutine()
  412.         { 
  413.             // Set our internal running flag to true so we can keep looping the thread for
  414.             // as long as required. Calling the Disconnect function will terminate the 
  415.             // background thread.
  416.             m_running = true;
  417.  
  418.             // start the thread loop.
  419.             while (m_running)
  420.             {
  421.                 // Surround the precise working of the process loop with a try-catch statement.
  422.                 // This allows us to catch errors and call the Disconnect function to properly
  423.                 // exit the loop.
  424.                 try
  425.                 {
  426.                     // Check if the socket is still available. If the socket is no longer available, raise an
  427.                     // exception.
  428.                     if (m_socket != null)
  429.                     {
  430.                         // Lock the socket here for exclusive access.
  431.                         lock (m_lock)
  432.                         {
  433.                             // Reevaluate the socket, connected property and the amount of data available.
  434.                             if ((m_socket != null) && Connected && (m_socket.Available > 0))
  435.                             {
  436.                                 // Copy the data available into a seperate variable. This allows us to
  437.                                 // perform a snapshot read operation on the socket and read the data
  438.                                 // in bursts from the socket.
  439.                                 int data_available = m_socket.Available;
  440.  
  441.                                 // Create the buffer that will hold the data for us.
  442.                                 byte[] buffer = new byte[data_available];
  443.  
  444.                                 // Now perform the read operation on the socket to receive the data
  445.                                 // that has been made available to us.
  446.                                 int bytes_read = m_socket.Receive(buffer, 0, data_available, SocketFlags.None);
  447.  
  448.                                 // Raise the onData event with the information we just received.
  449.                                 RaiseOnDataEvent(buffer, bytes_read, (m_socket.RemoteEndPoint as IPEndPoint).Address.ToString(), (m_socket.RemoteEndPoint as IPEndPoint).Port);
  450.                             }
  451.                         }
  452.  
  453.                         // Sleep the thread for 10ms to prevent resource hogging of the backgroundthread
  454.                         Thread.Sleep(10);
  455.                     }
  456.                     else
  457.                     {
  458.                         // The internal socket is no longer available. Throw an exception so we can properly shutdown the
  459.                         // IClient implementation and terminate the background thread.
  460.                         throw new Exception("The internal socket has been closed/disposed.");
  461.                     }
  462.                 }
  463.                 catch (Exception ex)
  464.                 {
  465.                     // Raise the onError event.
  466.                     RaiseOnErrorEvent("ListenRoutine", ex);
  467.  
  468.                     // Call the disconnect function to properly terminte the IClient and the background thread.
  469.                     // Calling the disconnect function will also raise the onDisconnect event.
  470.                     Disconnect();
  471.                 }
  472.             }
  473.         }
  474.  
  475.         /// <summary>
  476.         /// Raises the onConnect event from the calling code. The event can be raised synchronously or asynchronously 
  477.         /// depending on the value indicated by the Asynchronous property of the class.
  478.         /// </summary>
  479.         /// <param name="address">The remote address of the connection.</param>
  480.         /// <param name="port">The remote port of the connection.</param>
  481.         /// <seealso cref="Asynchronous"/>
  482.         protected virtual void RaiseOnConnectEvent(string address, int port)
  483.         { 
  484.             // Copy the event handler first to a loca variable. This prevents
  485.             // racing conditions between invoking the event and classes
  486.             // unsubscribing from the event.
  487.             EventHandler<ConnectionArguments> handle = m_event_connect;
  488.  
  489.             // Check if the handle has a value. If the handle is null, then no
  490.             // other classes/functions are subscribed to this event.
  491.             if (handle != null)
  492.             {
  493.                 // Obtain the invocation list to raise the event for each subscriber.
  494.                 Delegate[] pointers = handle.GetInvocationList();
  495.  
  496.                 // Loop through the entire list and invoke each event depending
  497.                 // on the settings. Surround the invoke with try-catch to catch
  498.                 // exception and not to interrupt the invokes.
  499.                 foreach (Delegate fpointer in pointers)
  500.                 {
  501.                     try
  502.                     {
  503.                         if (Asynchronous) (fpointer as EventHandler<ConnectionArguments>).BeginInvoke(this, new ConnectionArguments(address, port, this), new AsyncCallback(ConnectionCallback), null);
  504.                         else (fpointer as EventHandler<ConnectionArguments>)(this, new ConnectionArguments(address, port, this));
  505.                     }
  506.                     catch{ /* empty catch block */ }
  507.                 }
  508.             }
  509.         }
  510.  
  511.         /// <summary>
  512.         /// Raises the onError event from the calling code. The event can be raised synchronously or asynchronously 
  513.         /// depending on the value indicated by the Asynchronous property of the class.
  514.         /// </summary>
  515.         /// <param name="functionName">The name of the function that has caused the error to occur.</param>
  516.         /// <param name="message">The short simple error message related to the function.</param>
  517.         /// <param name="innerMessage">The long detailed error message related to the function.</param>
  518.         /// <param name="stackTrace">The stacktrace of the function at the time the error occured.</param>
  519.         /// /// <remarks>When events are raised asynchronously, they are raised in sequence of each other, but the events do not wait for the previous event to finish. In synchronous operation, each event wait untill the previous event has finished.</remarks>
  520.         protected virtual void RaiseOnErrorEvent(string functionName, string message, string innerMessage, string stackTrace)
  521.         { 
  522.             // Copy the eventhandler to a local variable to eliminate racing conditions.
  523.             EventHandler<Components.EventArgs.ErrorArguments> handle = m_event_error;
  524.  
  525.             // Check if there are subscribers for this event.
  526.             if (handle != null)
  527.             {
  528.                 // Obtain the invocation list to raise the event for each subscriber.
  529.                 Delegate[] handlers = handle.GetInvocationList();
  530.  
  531.                 // Loop over each subsribed delegate.
  532.                 foreach (Delegate fpointer in handlers)
  533.                 {
  534.                     try
  535.                     {
  536.                         if (Asynchronous) (fpointer as EventHandler<ErrorArguments>).BeginInvoke(this, new ErrorArguments(functionName, message, innerMessage, stackTrace), new AsyncCallback(ErrorCallback), null);
  537.                         else (fpointer as EventHandler<ErrorArguments>)(this, new ErrorArguments(functionName, message, innerMessage, stackTrace));
  538.                     }
  539.                     catch { /* empty catch block */ }
  540.                 }
  541.             }
  542.         }
  543.  
  544.         /// <summary>
  545.         /// Raises the onError event from the calling code. The event can be raised synchronously or asynchronously
  546.         /// depending on the value indicated by the Aynchronous property of the class.
  547.         /// </summary>
  548.         /// <param name="functionName">The name of the function that has caused the error to occur.</param>
  549.         /// <param name="ex">The exception that has been raised by the function.</param>
  550.         /// <remarks>When events are raised asynchronously, they are raised in sequence of each other, but the events do not wait for the previous event to finish. In synchronous operation, each event wait untill the previous event has finished.</remarks>
  551.         protected virtual void RaiseOnErrorEvent(string functionName, Exception ex)
  552.         {
  553.             RaiseOnErrorEvent(functionName, ex.Message, (ex.InnerException != null) ? ex.InnerException.Message : string.Empty, ex.StackTrace);
  554.         }
  555.  
  556.         /// <summary>
  557.         /// Raises the onData event from the calling code. The event can be raised synchronously or asynchronously
  558.         /// depending on the value indicated by the Aynchronous property of the class.
  559.         /// </summary>
  560.         /// <param name="data">The raw binary data read from the socket.</param>
  561.         /// <param name="size">The size of the data in the array.</param>
  562.         /// <param name="address">The remote address the data came from.</param>
  563.         /// <param name="port">The remote port the data came from.</param>
  564.         protected virtual void RaiseOnDataEvent(byte[] data, int size, string address, int port)
  565.         {
  566.             // Copy the eventhandler to a local variable to eliminate racing conditions.
  567.             EventHandler<EventArgs.DiagramArguments> handle = m_event_data;
  568.  
  569.             // Check if the handle has a value. If the handle is null, then no
  570.             // other classes/functions are subscribed to this event.
  571.             if (handle != null)
  572.             {
  573.                 // Obtain the invocation list to raise the event for each subscriber.
  574.                 Delegate[] pointers = handle.GetInvocationList();
  575.  
  576.                 // Loop through the entire list and invoke each event depending
  577.                 // on the settings. Surround the invoke with try-catch to catch
  578.                 // exception and not to interrupt the invokes.
  579.                 foreach (Delegate fpointer in pointers)
  580.                 {
  581.                     try
  582.                     {
  583.                         if (Asynchronous) (fpointer as EventHandler<DiagramArguments>).BeginInvoke(this, new DiagramArguments(data, size, new ConnectionArguments(address, port, this)), new AsyncCallback(DataCallback), null);
  584.                         else (fpointer as EventHandler<DiagramArguments>)(this, new DiagramArguments(data, size, new ConnectionArguments(address, port, this)));
  585.                     }
  586.                     catch { /* empty catch block to supress warnings. */ }
  587.                 }
  588.             }
  589.         }
  590.  
  591.         /// <summary>
  592.         /// Raises the OnDisconnect event from the calling code. The event can be raised synchronously or asynchronously
  593.         /// depending on the value indicated by the Aynchronous property of the class.
  594.         /// </summary>
  595.         /// <param name="address">The remote address of the connection.</param>
  596.         /// <param name="port">The remote port of the connection.</param>
  597.         protected virtual void RaiseOnDisconnectEvent(string address, int port)
  598.         {
  599.             // Copy the eventhandler to a local variable to eliminate racing conditions.
  600.             EventHandler<ConnectionArguments> handle = m_event_disconnect;
  601.  
  602.             // Check if there are subscribers for the event.
  603.             if (handle != null)
  604.             {
  605.                 // Obtain the invocation list to raise the event for each subscriber.
  606.                 Delegate[] pointers = handle.GetInvocationList();
  607.  
  608.                 // Loop through the entire list and invoke each event depending
  609.                 // on the settings. Surround the invoke with try-catch to catch
  610.                 // exception and not to interrupt the invokes.
  611.                 foreach (Delegate fpointer in pointers)
  612.                 {
  613.                     try
  614.                     {
  615.                         if (Asynchronous) (fpointer as EventHandler<ConnectionArguments>).BeginInvoke(this, new ConnectionArguments(address, port, this), new AsyncCallback(ConnectionCallback), null);
  616.                         else (fpointer as EventHandler<ConnectionArguments>)(this, new ConnectionArguments(address, port, this));
  617.                     }
  618.                     catch { /* empty catch block to supress warnings. */ }
  619.                 }
  620.             }
  621.         }
  622.  
  623.         /// <summary>
  624.         /// Cleans and releases all the resources held by the delegate that was used to invoke
  625.         /// the OnConnect/OnDisconnect event asynchronously from the calling code.
  626.         /// </summary>
  627.         /// <param name="result">The IAsyncResult containing a reference to the delegate that has invoked the event.</param>
  628.         protected virtual void ConnectionCallback(IAsyncResult result)
  629.         {
  630.             // Cast the IAsyncResult first to a concrete AsyncResult implementation. This allows 
  631.             // us to access the delegate that has the resources we need to clean.
  632.             System.Runtime.Remoting.Messaging.AsyncResult aresult = result as System.Runtime.Remoting.Messaging.AsyncResult;
  633.  
  634.             // Access the delegate of the asyncresult and cast this to the same type of delegate
  635.             // we used to invoke the result. After the cast, call the EndInvoke operation to
  636.             // release all resources held by the delegate.
  637.             (aresult.AsyncDelegate as EventHandler<EventArgs.ConnectionArguments>).EndInvoke(result);
  638.         }
  639.  
  640.         /// <summary>
  641.         /// Cleans and releases all the resources held by the delegate that was used to invoke
  642.         /// the OnData event asynchronously from the calling code.
  643.         /// </summary>
  644.         /// <param name="result">The IAsyncResult containing a reference to the delegate that has invoked the event.</param>
  645.         protected virtual void DataCallback(IAsyncResult result)
  646.         {
  647.             // Cast the IAsyncResult first to a concrete AsyncResult implementation. This allows 
  648.             // us to access the delegate that has the resources we need to clean.
  649.             System.Runtime.Remoting.Messaging.AsyncResult aresult = result as System.Runtime.Remoting.Messaging.AsyncResult;
  650.  
  651.             // Access the delegate of the asyncresult and cast this to the same type of delegate
  652.             // we used to invoke the result. After the cast, call the EndInvoke operation to
  653.             // release all resources held by the delegate.
  654.             (aresult.AsyncDelegate as EventHandler<EventArgs.DiagramArguments>).EndInvoke(result);
  655.         }
  656.  
  657.         /// <summary>
  658.         /// Cleans and releases all the resources held by the delegate that was used to invoke
  659.         /// the onError event asynchronously from the calling code.
  660.         /// </summary>
  661.         /// <param name="result">The IAsyncResult containing a reference to the delegate that has invoked the event.</param>
  662.         protected virtual void ErrorCallback(IAsyncResult result)
  663.         {
  664.             // Cast the IAsyncResult first to a concrete AsyncResult implementation. This allows 
  665.             // us to access the delegate that has the resources we need to clean.
  666.             System.Runtime.Remoting.Messaging.AsyncResult aresult = result as System.Runtime.Remoting.Messaging.AsyncResult;
  667.  
  668.             // Access the delegate of the asyncresult and cast this to the same type of delegate
  669.             // we used to invoke the result. After the cast, call the EndInvoke operation to
  670.             // release all resources held by the delegate.
  671.             (aresult.AsyncDelegate as EventHandler<Components.EventArgs.ErrorArguments>).EndInvoke(result);
  672.         }
  673.         #endregion
  674.  
  675.         #region Private Fields
  676.  
  677.         EventHandler<DiagramArguments> m_event_data;            // EventHandler to invoke the OnDisconnect event.
  678.         EventHandler<ConnectionArguments> m_event_connect;      // EventHandler to invoke the OnConnect event.
  679.         EventHandler<ConnectionArguments> m_event_disconnect;   // EventHandler to invoke the OnDisconnect event.
  680.         EventHandler<ErrorArguments> m_event_error;             // The Eventhandler to invoke the onError event.
  681.         Socket m_socket;                                        // The Berkley socket for TCP communications.
  682.         Thread m_backgroundthread;                              // The background thread that listens for incoming data.
  683.         readonly object m_lock;                                 // Lock for multithreaded access to the component.
  684.         IPEndPoint m_local_endpoint;                            // The local endpoint to establish a connection from.
  685.         IPEndPoint m_remote_endpoint;                           // The remote endpoint to establish a connection with.
  686.         bool m_asynchronous;                                    // Value indicating whether our object is running asynchronously.
  687.         bool m_running;                                         // Value for controlling the background thread.
  688.         bool m_connected;                                       // Value indicating whether or not we're connected.
  689.  
  690.         #endregion
  691.     }
  692. }
  693.  
The server is basicly the same with a socket in listen mode.
Oct 6 '10 #1
3 3658
Airslash
221 100+
After some feedback from the sysadmin, a VPN is created between our network and the remote network.

I'm able to ping the remote location from my system, but on the remote system, I cannot ping my computer. I can establish a remote desktop connection however.

Is this an issue in .NET? Normal applications work fine, but when I try to create a .NET Socket connection between the two, I cannot establish it.
The Client reports the remote location to be accessible, but the remote location cannot respond...
Oct 11 '10 #2
Plater
7,872 Expert 4TB
Hmm, there is a lot of code and i only skimmed so forgive me if you have done this already, but are you providing the local_endpoint with specific data?
You may need to provide more exact details for the local end point then the standard ipany and port 0.
Especially if you are using a specific port-based tunnel, or if the tunnel is created on a different "interface" (VPNs like cisco seem to make a virtual "network card" that gets used).
Maybe take a look at that?
Oct 13 '10 #3
Airslash
221 100+
We found the issue eventually.
Bad NAT rules on the router connecting to the outside network. We could see the destination, but the destination could not see us.

Once the SysOps changed the NAT rules, everything worked like a charm.
Oct 13 '10 #4

Sign in to post your reply or Sign up for a free account.

Similar topics

3
by: tperovic | last post by:
Hi, I have an application that uses ADO & VBA to connect to SQL Server 2000 periodically like this: Dim conn As ADODB.Connection Set conn = New ADODB.Connection conn.ConnectionTimeout = 1...
7
by: C# beginner | last post by:
I'm struggling with a timeout problem today. ConnectionString = "Integrated Security=true;Database=MyDatabase;Data Source=(local); Connection Timeout = 180;"; My connection string is set as...
2
by: David Lozzi | last post by:
Hello, I have a website I'm developing that will query a SQL database for basic lists. If the database is unavailable, the site will continue to function as a static site. The problem I'm...
4
by: Shachar | last post by:
Hi All, When I call a web service on the IIS 5 or 6 I see the connection count increase by 1 user, but after a minute the connection is close, connection count decrease by 1 user, I see it...
0
by: Christopher H. Laco | last post by:
I'm in a strange situation. I have a dataset that uses it own connection string from MySettings. All is well. This thing works in .NET just dandy. If I reference this dataset from another...
6
by: michael sorens | last post by:
I have used the visual designer to create a series of DataGridViews populated from SQLServer data. A typical call is: myCountsTableAdapter.Fill(myDataSet.myCounts); My application actually...
4
by: Julia | last post by:
Hello everyone, I have an Access 2003 (2000 format) front end application with SQL 2000 back end that is being used by about 20 users on a daily basis (using local copy of .mdb file). Ever since...
3
by: Amar Gaikwad | last post by:
Hi All, I want to read the contents (only the filenames) from the ftp server. The code which I have throws connection timeout exception :: "A connection attempt failed because the connected...
3
by: =?Utf-8?B?QXho?= | last post by:
Is there a limitation on the number of (sequential) opened connection for SQL Server User Instances? The following method will run to about the 240th iteration then will receive a timeout...
8
by: Charlotte | last post by:
Hi, the connection timeout in my IIS (webserver in a LAN) is now 600 (600 seconds = 10 minutes) I want to set the connectiontimeout to 3600 (1 hour) or may I set the timeout for 36000...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.