我有一个TcpClient对象,它使用底层的NetworkStream.Write()将一些数据发送到服务器。 因此,我有:
TcpClient server = new TcpClient(serverName, 50001);
/* ... */
NetworkStream stream = server.GetStream();
现在,按下按钮时,连接应该关闭。 什么是关闭连接的正确方法? MSDN文档说关闭TcpClient(使用.Close())实际上并不关闭套接字,只关闭TcpClient资源(这至少是我理解文档的方式)。
那么,下一个代码会正确关闭连接吗?
stream.Close();
server.Close();
这是否足够,或者我应该首先检查(以某种方式)是否可以关闭流(或服务器)(如果连接是半开的或者某种东西)......
更多,NetworkStream.Close()
MSDN文档声明它会释放资源(甚至是套接字),因此关闭流就足够了,因为我在此之后阻止使用TcpClient。
什么是正确的方法?
答案 0 :(得分:6)
正如the docs所说:
调用此方法最终将导致关联的Socket关闭,并且还将关闭用于发送和接收数据的相关NetworkStream(如果已创建)。
所以server.Close();
就够了。
首先关闭NetworkStream绝对不会受到伤害。
顺便说一句,如果您恰好只在一个方法中使用TcpClient,请将其包装在using( )
语句中,以便您确定Dispose()
(相当于Close()
)即使抛出异常等,也会调用它。
答案 1 :(得分:3)
我将TCP连接与套接字关联。
一般来说,程序是这样的: 1.完成发送数据 2.使用SocketShutdown.Send参数调用Socket.Shutdown 3.循环接收,直到它返回0或因异常而失败 4.调用Close()
这是伪代码中的一个小样本,与C#非常相似:)
void CloseConnection(Socket socket)
{
socket.Send(/*last data of the connection*/);
socket.Shutdown(SocketShutdown.Send);
try
{
int read = 0;
while( (read = socket.Receive(/*application data buffers*/)) > 0 )
{}
}
catch
{
//ignore
}
socket.Close();
}
如果跳过第一步和第三步 - 可能会发生数据丢失。
答案 2 :(得分:0)
关闭流然后关闭服务器是正确的。这应该会导致所有套接字随着时间的推移成功关闭,如文档所述。然而,随着时间的推移,几个头脑痒痒的错误教会了我一个重要的教训:
别忘了冲洗!
stream.Flush();
stream.Close();
server.Close();
您经常会丢失一些您认为可能已发送的数据。这也有助于确保在关闭流时应该为空并且不活动。