469,918 Members | 2,226 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,918 developers. It's quick & easy.

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:
http://msdn2.microsoft.com/en-us/lib...nt(VS.71).aspx

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

Expand|Select|Wrap|Line Numbers
  1. int PortNum = 10000;
  2. TcpListener objTcpListen = new TcpListener(IPAddress.Any,PortNum );
  3. MyTcpClient objectMyTcpClient = this.objTcpListen.AcceptTcpClient(); <-- Generates the Invalid Cast Exception
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
********************************************
Expand|Select|Wrap|Line Numbers
  1. public class MyTcpClient : TcpClient
  2.     {
  3.         // Constructor for the derived class.
  4.         public MyTcpClient () : base()
  5.         {
  6.         }
  7.         public MyTcpClient (string pHostname, int pPort) : base(pHostname,pPort)
  8.         {
  9.         }
  10.         public MyTcpClient (System.Net.Sockets.AddressFamily pFamily) : base(pFamily)
  11.         {
  12.         }
  13.         public MyTcpClient (System.Net.IPEndPoint pLocalEP) : base(pLocalEP)
  14.         {
  15.         }
  16.  
  17.  
  18.         public bool getActive 
  19.         {
  20.             get
  21.             {
  22.                 return this.Active;
  23.             }
  24.         }
  25.         public Socket getSocket 
  26.         {
  27.             get
  28.             {
  29.                 return this.Client;
  30.             }
  31.         }        
  32.     }
Jan 17 '08 #1
11 2212
RedSon
5,000 Expert 4TB
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
Jan 17 '08 #2
RedSon
5,000 Expert 4TB
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:
http://msdn2.microsoft.com/en-us/lib...nt(VS.71).aspx

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

Expand|Select|Wrap|Line Numbers
  1. int PortNum = 10000;
  2. TcpListener objTcpListen = new TcpListener(IPAddress.Any,PortNum );
  3. MyTcpClient objectMyTcpClient = this.objTcpListen.AcceptTcpClient(); <-- Generates the Invalid Cast Exception
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
********************************************
Expand|Select|Wrap|Line Numbers
  1. public class MyTcpClient : TcpClient
  2.     {
  3.         // Constructor for the derived class.
  4.         public MyTcpClient () : base()
  5.         {
  6.         }
  7.         public MyTcpClient (string pHostname, int pPort) : base(pHostname,pPort)
  8.         {
  9.         }
  10.         public MyTcpClient (System.Net.Sockets.AddressFamily pFamily) : base(pFamily)
  11.         {
  12.         }
  13.         public MyTcpClient (System.Net.IPEndPoint pLocalEP) : base(pLocalEP)
  14.         {
  15.         }
  16.  
  17.  
  18.         public bool getActive 
  19.         {
  20.             get
  21.             {
  22.                 return this.Active;
  23.             }
  24.         }
  25.         public Socket getSocket 
  26.         {
  27.             get
  28.             {
  29.                 return this.Client;
  30.             }
  31.         }        
  32.     }
Have you tried explicitly casting it to MyTcpClient? Alternatively you can try

Expand|Select|Wrap|Line Numbers
  1. MyTcpClient objectMyTcpClient = new MyTcpClient(this.objTcpListen.AcceptTcpClient()));
Jan 17 '08 #3
Plater
7,872 Expert 4TB
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.Client like this:
Expand|Select|Wrap|Line Numbers
  1. Socket s = myTcpClient.Client;
  2.  
Jan 17 '08 #4
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.
Jan 17 '08 #5
Have you tried explicitly casting it to MyTcpClient? Alternatively you can try

Expand|Select|Wrap|Line Numbers
  1. MyTcpClient objectMyTcpClient = new MyTcpClient(this.objTcpListen.AcceptTcpClient()));

Sorry about that, yes I have tried that, here is the code the I tried:
Expand|Select|Wrap|Line Numbers
  1. int PortNum = 10000;
  2. TcpListener objTcpListen = new TcpListener(IPAddress.Any,PortNum );
  3. MyTcpClient objectMyTcpClient = (MyTcpClient)this.objTcpListen.AcceptTcpClient(); <-- Generates the Invalid Cast Exception
  4.  
Jan 17 '08 #6
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.Client like this:
Expand|Select|Wrap|Line Numbers
  1. Socket s = myTcpClient.Client;
  2.  
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.
Jan 17 '08 #7
Plater
7,872 Expert 4TB
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?
Jan 17 '08 #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?

When the data is sent to Computer B, How do I send it from a Port that I am Listening to?
Jan 17 '08 #9
Plater
7,872 Expert 4TB
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.
Jan 17 '08 #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.
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:
Expand|Select|Wrap|Line Numbers
  1. System.Net.Sockets.SocketException: Only one usage of each socket address (proto
  2. col/network address/port) is normally permitted
  3.    at System.Net.Sockets.Socket.Bind(EndPoint localEP)
  4.    at System.Net.Sockets.TcpClient..ctor(IPEndPoint localEP)
  5.    at SIMServer.Server.HandleClientCommMicros() 
Jan 17 '08 #11
Plater
7,872 Expert 4TB
Can you maintain the connected state?
Like keep each socket open and then just data back and forth?
Jan 18 '08 #12

Post your reply

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

Similar topics

8 posts views Thread by Grant Richard | last post: by
3 posts views Thread by Alessandro | last post: by
1 post views Thread by Nuno Magalhaes | last post: by
5 posts views Thread by Nick Flandry | last post: by
reply views Thread by den 2005 | last post: by
1 post views Thread by Waqarahmed | last post: by
reply views Thread by Salome Sato | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.