C# APP .Net 1.1 - Invalid Cast Error using Derived TcpClient with TCPListener

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • batmanfreeze
    New Member
    • Jan 2008
    • 6

    C# APP .Net 1.1 - Invalid Cast Error using Derived TcpClient with TCPListener

    I am using C# in .Net 1.1, and need to access the 'Client' Property of TcpClient, so I created a derived class to do this based upon the Microsoft Sample, located at:


    The only problem is that in my main app, when I try to do the following, I get an Invalid Cast Exception:

    [CODE=csharp]int PortNum = 10000;
    TcpListener objTcpListen = new TcpListener(IPA ddress.Any,Port Num );
    MyTcpClient objectMyTcpClie nt = this.objTcpList en.AcceptTcpCli ent(); <-- Generates the Invalid Cast Exception[/CODE]

    Does anyone know how to deal with this issue?

    There was a post on the Microsoft Public Newsgroup that posted the same question, except this user was using VB. Unfortunately he withdrew his question, so there was no answer. http://www.thescripts.com/forum/thread371494.html


    *************** *************** **************
    My TcpClient Derived Class
    *************** *************** **************
    [CODE=csharp]public class MyTcpClient : TcpClient
    {
    // Constructor for the derived class.
    public MyTcpClient () : base()
    {
    }
    public MyTcpClient (string pHostname, int pPort) : base(pHostname, pPort)
    {
    }
    public MyTcpClient (System.Net.Soc kets.AddressFam ily pFamily) : base(pFamily)
    {
    }
    public MyTcpClient (System.Net.IPE ndPoint pLocalEP) : base(pLocalEP)
    {
    }


    public bool getActive
    {
    get
    {
    return this.Active;
    }
    }
    public Socket getSocket
    {
    get
    {
    return this.Client;
    }
    }
    }[/CODE]
    Last edited by RedSon; Jan 17 '08, 08:01 PM. Reason: CODE
  • RedSon
    Recognized Expert Expert
    • Jan 2007
    • 4980

    #2
    Thank you for your well researched and asked question, it is refreshing to see that some people understand how to ask a question on a forum. Please be aware of our code posting feature. You can post your code in [code] tags (See How to Ask a Question).

    This makes it easier for our Experts to read and understand it. Failing to do so creates extra work for the moderators, thus wasting resources, otherwise available to answer the members' questions.

    Please use [code] tags in future.

    MODERATOR

    Comment

    • RedSon
      Recognized Expert Expert
      • Jan 2007
      • 4980

      #3
      Originally posted by batmanfreeze
      I am using C# in .Net 1.1, and need to access the 'Client' Property of TcpClient, so I created a derived class to do this based upon the Microsoft Sample, located at:


      The only problem is that in my main app, when I try to do the following, I get an Invalid Cast Exception:

      [CODE=csharp]int PortNum = 10000;
      TcpListener objTcpListen = new TcpListener(IPA ddress.Any,Port Num );
      MyTcpClient objectMyTcpClie nt = this.objTcpList en.AcceptTcpCli ent(); <-- Generates the Invalid Cast Exception[/CODE]

      Does anyone know how to deal with this issue?

      There was a post on the Microsoft Public Newsgroup that posted the same question, except this user was using VB. Unfortunately he withdrew his question, so there was no answer. http://www.thescripts.com/forum/thread371494.html


      *************** *************** **************
      My TcpClient Derived Class
      *************** *************** **************
      [CODE=csharp]public class MyTcpClient : TcpClient
      {
      // Constructor for the derived class.
      public MyTcpClient () : base()
      {
      }
      public MyTcpClient (string pHostname, int pPort) : base(pHostname, pPort)
      {
      }
      public MyTcpClient (System.Net.Soc kets.AddressFam ily pFamily) : base(pFamily)
      {
      }
      public MyTcpClient (System.Net.IPE ndPoint pLocalEP) : base(pLocalEP)
      {
      }


      public bool getActive
      {
      get
      {
      return this.Active;
      }
      }
      public Socket getSocket
      {
      get
      {
      return this.Client;
      }
      }
      }[/CODE]
      Have you tried explicitly casting it to MyTcpClient? Alternatively you can try

      Code:
      MyTcpClient objectMyTcpClient = new MyTcpClient(this.objTcpListen.AcceptTcpClient()));

      Comment

      • Plater
        Recognized Expert Expert
        • Apr 2007
        • 7872

        #4
        You are attempting to "up" cast and not "down" cast, which you cannot do in the method you have tried.

        If you have ClassA inherited from BaseClassA.
        You can cast ClassA as BaseClassA, but an instance of BaseClassA cannot be cast as an instance of ClassA (as you are seeing in your error).
        What you can do is make your custom class have a constructor that takes in the TcpClient as a parameter, but I'm not sure that buys you anything.

        What do you need to do with the underlying socket of TcpClient? (by the way, TcpListener also has an AcceptSocket() call that returns the Socket)
        I've had no trouble using myTcpClient.Cli ent like this:
        Code:
        Socket s = myTcpClient.Client;

        Comment

        • batmanfreeze
          New Member
          • Jan 2008
          • 6

          #5
          Originally posted by RedSon
          Thank you for your well researched and asked question, it is refreshing to see that some people understand how to ask a question on a forum. Please be aware of our code posting feature. You can post your code in [code] tags (See How to Ask a Question).

          This makes it easier for our Experts to read and understand it. Failing to do so creates extra work for the moderators, thus wasting resources, otherwise available to answer the members' questions.

          Please use [code] tags in future.

          MODERATOR
          Noted, I will do that in the future. And Thank you for letting me know.

          Comment

          • batmanfreeze
            New Member
            • Jan 2008
            • 6

            #6
            Originally posted by RedSon
            Have you tried explicitly casting it to MyTcpClient? Alternatively you can try

            Code:
            MyTcpClient objectMyTcpClient = new MyTcpClient(this.objTcpListen.AcceptTcpClient()));

            Sorry about that, yes I have tried that, here is the code the I tried:
            Code:
            int PortNum = 10000;
            TcpListener objTcpListen = new TcpListener(IPAddress.Any,PortNum );
            MyTcpClient objectMyTcpClient = (MyTcpClient)this.objTcpListen.AcceptTcpClient(); <-- Generates the Invalid Cast Exception

            Comment

            • batmanfreeze
              New Member
              • Jan 2008
              • 6

              #7
              Originally posted by Plater
              You are attempting to "up" cast and not "down" cast, which you cannot do in the method you have tried.

              If you have ClassA inherited from BaseClassA.
              You can cast ClassA as BaseClassA, but an instance of BaseClassA cannot be cast as an instance of ClassA (as you are seeing in your error).
              What you can do is make your custom class have a constructor that takes in the TcpClient as a parameter, but I'm not sure that buys you anything.

              What do you need to do with the underlying socket of TcpClient? (by the way, TcpListener also has an AcceptSocket() call that returns the Socket)
              I've had no trouble using myTcpClient.Cli ent like this:
              Code:
              Socket s = myTcpClient.Client;
              I am essentially creating a Network Relay application for communication between 2 networked sytems. My application will reside on a seperate server.

              First, I have 2 TcpListeners, on Ports A and B

              1) I receive a TCP message on 'Port A' from 'System 1' and relay it to 'Port B' on 'System 2'.

              2) 'System 2' responds to the same IP and Port that communicated with it (This I cannot change). Now I receive that response on 'Port B' and relay it back to 'Port A' on 'System 1'

              'System 1' <----> Server <----> 'System 2'

              I am trying to make sure that I keep the communication flowing in the proper direction.

              Also when I send my communication to 'System 2', if I create a new TcpClient object and send it a message, that will work, but it sends it from a random port. I need it to send from the same port number that my TcpListener for 'Port B' is on.

              Comment

              • Plater
                Recognized Expert Expert
                • Apr 2007
                • 7872

                #8
                So you just want to sit like a proxy in between the two.
                Ports normally only matter on the receiving side.

                So ComputerA talks through you to ComputerB and back?
                ComputerA <->(your server) <->ComputerB

                So ComputerA will attempt to talk to port X (which will be on your server)
                You then need to contact port X on ComputerB and pass along any data from ComputerA.
                ComputerB can reply and have it sent on to ComputerA.

                So any data that comes in on the 1st socket, send to the 2nd socket, and any data that comes in on the 2nd socket send to the 1st socket.

                What am I missing on this?

                Comment

                • batmanfreeze
                  New Member
                  • Jan 2008
                  • 6

                  #9
                  Originally posted by Plater
                  So you just want to sit like a proxy in between the two.
                  Ports normally only matter on the receiving side.

                  So ComputerA talks through you to ComputerB and back?
                  ComputerA <->(your server) <->ComputerB

                  So ComputerA will attempt to talk to port X (which will be on your server)
                  You then need to contact port X on ComputerB and pass along any data from ComputerA.
                  ComputerB can reply and have it sent on to ComputerA.

                  So any data that comes in on the 1st socket, send to the 2nd socket, and any data that comes in on the 2nd socket send to the 1st socket.

                  What am I missing on this?

                  When the data is sent to Computer B, How do I send it from a Port that I am Listening to?

                  Comment

                  • Plater
                    Recognized Expert Expert
                    • Apr 2007
                    • 7872

                    #10
                    The "from" port shouldn't matter, as long as the "to" ports are correct, neither device should be able to tell the difference.

                    It might be possible in socket creation stuff, to dictate a LocalEndPoint (where you could set the FROM port) but I don't know for sure.

                    Comment

                    • batmanfreeze
                      New Member
                      • Jan 2008
                      • 6

                      #11
                      Originally posted by Plater
                      The "from" port shouldn't matter, as long as the "to" ports are correct, neither device should be able to tell the difference.

                      It might be possible in socket creation stuff, to dictate a LocalEndPoint (where you could set the FROM port) but I don't know for sure.
                      Ok. That is good to know. I am going to try the ideas I've gotten from our discussion. I'll let you know what happens. Thanks for the discussion.

                      Just so that you know, here are the 2 Scenarios that I have tried:

                      1) When I get a message from Computer A, I create a TCPClient object and relay the data to Computer B. Computer B receives the data, but the Port that it shows that I sent from is random, and I am not listening to that port.

                      2) I try to create a TCPClient with the LocalIPEndPoint constructor, and I get the following runtime error:
                      Code:
                      System.Net.Sockets.SocketException: Only one usage of each socket address (proto
                      col/network address/port) is normally permitted
                         at System.Net.Sockets.Socket.Bind(EndPoint localEP)
                         at System.Net.Sockets.TcpClient..ctor(IPEndPoint localEP)
                         at SIMServer.Server.HandleClientCommMicros()

                      Comment

                      • Plater
                        Recognized Expert Expert
                        • Apr 2007
                        • 7872

                        #12
                        Can you maintain the connected state?
                        Like keep each socket open and then just data back and forth?

                        Comment

                        Working...