C# - Passing TcpClient as parameter...

Associate
Joined
3 Dec 2006
Posts
594
When passing TcpClient as a parameter, does it pass it as a parameter just like any other variable/class, or does it do it by referencing? Let's say I pass a parameter to a new class in the new class Constructor and I declare a new variable of TcpClient which I assign the parameter to. At the end of this class (well, it's a Form, but anyway..) I perform TcpClient.Close() to close this new instantiation of TcpClient but it closes the other one too!

Here's a more detailed run-down of what's going on in the program:

Two clients contact each other, if both confirm the game, one sends confirmation to Server. Server gets both TcpClients from a hashtable, and then creates a new class with the two TcpClient's as parameters. The server also sends back a confirmation that things are ready for the clients.

The clients now create a new instantiation of the form with the TcpClient to the Server as a parameter.

Things run smoothly and fine the first time round, but when the two clients close down the forms and then try and re-initiate a game nothing happens. There's a way I can get the form to initiate (which means initial contact to the server works) by taking out TcpClient.Close() of the Form_onClosing() method in the client. The problem with this is that nothing else happens beyond the initial contact. The forms load, the server creates a new class but no further communication occurs which leads me to believe that there's something going wrong with either the streams or possibly one of the TcpClients... Any ideas please? I've been racking my brain on this for aaages!
 
If it's not a primitive, I believe it goes as by reference. Could be wrong though :) Does TcpClient have a Clone() method?
 
Nope, doesn't have a Clone() method.

Could it be the way I'm assigning the TcpClient in the new class(es)?

I'm declaring it with "TcpClient tcpPlayer1;" (for example) and then assigning it in the constructor using:

tcpPlayer1 = pTcpClient1; [pTcpClient1 is the parameter TcpClient]

So basically I'm not using the "new" keyword at all. I would've thought, though, that it works, seeing as how it works for the first time...
 
Every parameter that is a class is a reference. In that case, there is only one underlying socket connection, no matter how many references you have to the TcpClient object that contains it.

If you wanted two connections that could be closed independently then you have to initiate another one from scratch.
 
Ok, thanks. Is there anyway to make a new one from "scratch" by using an existing TcpClient? Or can that only be done using Connect()?

And any ideas on why the second-time-round doesn't work?
 
You must use the Connect() method of a fresh TcpClient created using new :)

It's easier to understand why copying the reference wouldn't work as you want it to by ignoring the part about it being passed as a parameter.
Code:
TcpClient c1 = new TcpClient();
c1.Connect( ... )

// c1 is a reference to a TcpClient object that has established a connection.

TcpClient c2 = c1;
TcpClient c3 = c1;
TcpClient c4 = c1;

// Only one TcpClient object was actually created. The variables c1 to c4 are all just references to that same object.

TcpClient c5 = new TcpClient();
c5.Connect( ... );

// c5 is a reference to a separate TcpClient object that has established its own connection.
 
Last edited:
Ok, I understand.

I've just been debugging this program, and it looks as if either the client or server is destroying the TcpClient to one another as the game closes... I really can't understand why though :/
 
If the TcpClient object was created inside a secondary form and that form was then closed, TcpClient would go out of scope and presumably explicitly shut down the connection in its destructor? Though I might have the wrong end of the stick :)
 
Last edited:
Why would it do that if it's being passed as reference? Does look like it's along the right track though. I'm getting an IOException error in the server in the thread that receives game requests. It says:

"An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host"

which I guess suggests that the client is shutting down the connection. Maybe it is when it closes down the form but I really don't see WHY it'd do that...

edit: or a similar error with "System.InvalidOperationException: The operation is not allowed on non-connected sockets." at the same spot, when trying to get the stream from the TcpClient.
 
Last edited:
If the TcpClient object was created inside a secondary form and that form was then closed, TcpClient would go out of scope and presumably explicitly shut down the connection in its destructor? Though I might have the wrong end of the stick :)

The garbage cleaner destroys objects only if no more in scope references exist to it. If it was created in a form which was destroyed the tcpclient object wouldn't be destroyed aswell if it has a refrence that has been assigned elsewhere.

We need some code Phyre, I'd hazard a guess that while you are passing it into the form an assigning a reference you aren't maintaining a reference outside the form.
 
Last edited:
Back
Top Bottom