Question Asker Question Asker - 1 year ago 38 Question

Which actions need to be performed on both ends for a TCP connection

I don't quite understand exactly how a few of the features are shared when a


Let's say the following code is run (for now ignore synchronisation):


Dim server As New TcpListener(localAddr, port)

Dim client As TcpClient = server.AcceptTcpClient()


Dim client As New TcpClient
client.Connect(hostAddr, port)

And the connection is successfully established. Now there are two
instances — one on server side and one on client side. However, they share the same network stream through

I'm slightly confused — does the client pass itself and all of its properties to the server when
is called?

What about any changes to either of the
instances after this? When the connection shuts down I call this on both sides:


But I get an exception with
on the client which executes this code the latest because it tells me that the client is already closed (this happens when the above code isn't perfectly synchronised on both sides).

What about the
properties? Do I need to set this on both sides of the connection?

Hope someone can clear up my confusion with an explanation of how exactly the
classes work during the communication — so far I haven't been able to find documentation explaining what exactly happens.

usr usr
Answer Source

The TCP protocol does not know what a TcpClient is. This is a .NET concept. TCP does not reference .NET concepts at all. For that reason no objects will be sent across the wire.

The only thing that is sent is the bytes you explicitly write.

Each side has it's own isolated objects. Both sides use their own TcpClient object which acts like a handle to the TCP connection.


This is not the proper shutdown sequence. The first line is redundant to the second and incomplete. Close should never be called. The best way to do it is to wrap the client in using. The second best way is to call Dispose on the client. The Close methods in the BCL are historic accidents and should be ignored. They do the same thing that Dispose does in all cases that I ever looked at.

Don't touch the buffer sizes. They control how much memory the kernel uses to buffer data on your end of the connection. The kernel is capable of managing this by itself.

Also don't look at the buffer sizes in your code. They are meaningless. Also don't use the DataAvailable property because if it returns false/0 this does not mean that no data can be read.

The Connected property is not necessarily synchronized on both sides. If the network goes down there can be no synchronization. Never look at the Connected property. If it says true the next nanosecond it could be false. So it's not possible to make decisions based on that property. You do not need to test anything. Just Read/Write and handle the exceptions by aborting.

Regarding packets, you are not sending packets when you Write. TCP has a boundaryless stream of bytes. The kernel packetizes your data internally. You do not need to split data into specific sizes. Just use a fairly big buffer size such as 8K (or more on fast networks). The write size is only about saving CPU time by being less chatty (assuming nagling is enabled).