当aTcpListener
和TcpClient
通信时,我不太清楚这些特性是如何共享的。
假设运行以下代码(暂时忽略同步):
服务器:
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/