对于TCP连接,需要在两端执行哪些操作

时间:2016-08-21 11:10:28

标签: vb.net tcp tcpclient tcplistener

TcpListenerTcpClient进行通信时,我并不完全清楚如何分享一些功能。

假设运行以下代码(暂时忽略同步):

服务器:

Dim server As New TcpListener(localAddr, port)
server.Start()

Dim client As TcpClient = server.AcceptTcpClient()

客户端:

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

连接成功建立。现在有两个TcpClient实例 - 一个在服务器端,一个在客户端。但是,它们通过TcpClient.GetStream()共享相同的网络流。

我有点困惑 - 当调用server.AcceptTcpClient()时,客户端是否将自身及其所有属性传递给服务器?

在此之后对TcpClient个实例之间的任何更改怎么办?当连接关闭时,我在双方都打电话:

client.GetStream.Close()
client.Close()

但是我在客户端上遇到TcpClient.GetStream.Close()的异常,它执行此代码是最新的,因为它告诉我客户端已经关闭(当上面的代码在两端都没有完全同步时会发生这种情况)。

.SendBufferSize.ReceiveBufferSize属性怎么样?我是否需要在连接的两侧设置它?

希望有人可以通过解释TcpClient/Listener类在沟通过程中的工作原理来解决我的困惑 - 到目前为止,我还没有找到解释究竟发生了什么的文档。

1 个答案:

答案 0 :(得分:2)

TCP协议不知道TcpClient是什么。这是一个.NET概念。 TCP根本不引用.NET概念。因此,不会通过电线发送任何对象。

唯一发送的是你明确写的字节。

每一方都拥有自己的孤立物体。双方都使用自己的TcpClient对象,它就像TCP连接的句柄一样。

client.GetStream.Close()
client.Close()

这不是正确的关机顺序。第一行是第二行,而第二行是不完整的。永远不应该打电话给关闭。最好的方法是将客户端包装在using中。第二种最好的方法是在客户端上调用Dispose。 BCL中的Close方法是历史事故,应予以忽略。他们做的事与Dispose在我曾经看过的所有情况下做的一样。

请勿触摸缓冲区大小。它们控制内核用于缓冲连接末端数据的内存量。内核能够自行管理它。

另外,请不要查看代码中的缓冲区大小。它们毫无意义。也不要使用DataAvailable属性,因为如果它返回false/0,这并不意味着无法读取数据。

Connected属性不一定在双方同步。如果网络出现故障,则无法进行同步。永远不要看Connected财产。如果它显示true下一个纳秒,它可能是false。因此,根据该属性做出决定是不可能的。你不需要测试任何东西。只需读/写并通过中止处理异常。

关于数据包,您Write时不发送数据包。 TCP具有无边界的字节流。内核在内部打包您的数据。您无需将数据拆分为特定大小。只需使用相当大的缓冲区大小,如8K(或更快的网络)。写入大小只是通过减少繁琐来节省CPU时间(假设启用了nagling)。