当aTcpListenerTcpClient通信时,我不太清楚这些特性是如何共享的。
假设运行以下代码(暂时忽略同步):
服务器:

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类在通信过程中的具体工作方式,从而消除我的困惑——到目前为止,我还没有找到解释具体发生了什么的文档。

最佳答案

tcp协议不知道aTcpClient是什么。这是一个.NET概念。TCP根本不引用.NET概念。因此,不会通过导线发送任何对象。
唯一发送的是显式写入的字节。
每一边都有自己的独立对象。双方都使用自己的TcpClient对象,该对象充当TCP连接的句柄。

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

这不是正确的关机顺序。第一行是多余的,第二行是不完整的。不应该叫close。最好的方法是将客户机包装在using中。第二种最好的方法是在客户机上调用Dispose。bcl中的Close方法是历史性的事故,应该被忽略。他们做的事情和我看过的所有案例中Dispose都一样。
不要触摸缓冲器的尺寸。它们控制内核在连接端使用多少内存来缓冲数据。内核能够自己管理这一点。
另外,不要查看代码中的缓冲区大小。它们毫无意义。也不要使用DataAvailable属性,因为如果它返回false/0这并不意味着无法读取任何数据。
Connected属性不一定在两侧同步。如果网络中断,就不能进行同步。永远不要查看Connected属性。如果它说下一纳秒是true,那么它可能是false。所以不可能基于这个属性做出决定。你不需要测试任何东西。只需读/写并通过中止来处理异常。
关于数据包,当您Write时不发送数据包。TCP有一个无边界的字节流。内核在内部对您的数据进行打包。您不需要将数据拆分为特定的大小。只需使用相当大的缓冲区大小,如8K(或在快速网络上更大)。写的大小只是通过减少聊天来节省CPU时间(假设启用了Nagling)。

关于vb.net - 对于TCP连接,需要在两端执行哪些操作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39063523/

10-10 04:54