回答(7)
2 years ago
我不建议您尝试编写仅用于测试套接字 . 并且不要在.NET的Connected属性上进行中继 .
如果您想知道远程 endpoints 是否仍处于活动状态,可以使用TcpConnectionInformation:
TcpClient client = new TcpClient(host, port);
IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
TcpConnectionInformation[] tcpConnections = ipProperties.GetActiveTcpConnections().Where(x => x.LocalEndPoint.Equals(client.Client.LocalEndPoint) && x.RemoteEndPoint.Equals(client.Client.RemoteEndPoint)).ToArray();
if (tcpConnections != null && tcpConnections.Length > 0)
{
TcpState stateOfConnection = tcpConnections.First().State;
if (stateOfConnection == TcpState.Established)
{
// Connection is OK
}
else
{
// No active tcp Connection to hostName:port
}
}
client.Close();
这里它是TcpClient的扩展方法 .
public static TcpState GetState(this TcpClient tcpClient)
{
var foo = IPGlobalProperties.GetIPGlobalProperties()
.GetActiveTcpConnections()
.SingleOrDefault(x => x.LocalEndPoint.Equals(tcpClient.Client.LocalEndPoint));
return foo != null ? foo.State : TcpState.Unknown;
}
2 years ago
据我所知/记得没有办法测试套接字是否连接而不是读取或写入 .
我根本没有使用过TcpClient,但是如果远程端已正常关闭,Socket类将从调用Read返回0 . 如果远程端没有正常关闭[我认为]你得到超时异常,不记得抱歉的类型 .
使用像' if(socket.Connected) { socket.Write(...) } 这样的代码会产生竞争条件 . 你最好只是调用socket.Write并处理异常和/或断开连接 .
2 years ago
@ uriel的答案对我很有用,但我需要在C / CLI中编写代码,这并非完全无关紧要 . 这是(大致相当的)C / CLI代码,添加了一些健壮性检查以获得良好的衡量标准 .
using namespace System::Net::Sockets;
using namespace System::Net::NetworkInformation;
TcpState GetTcpConnectionState(TcpClient ^ tcpClient)
{
TcpState tcpState = TcpState::Unknown;
if (tcpClient != nullptr)
{
// Get all active TCP connections
IPGlobalProperties ^ ipProperties = IPGlobalProperties::GetIPGlobalProperties();
array ^ tcpConnections = ipProperties->GetActiveTcpConnections();
if ((tcpConnections != nullptr) && (tcpConnections->Length > 0))
{
// Get the end points of the TCP connection in question
EndPoint ^ localEndPoint = tcpClient->Client->LocalEndPoint;
EndPoint ^ remoteEndPoint = tcpClient->Client->RemoteEndPoint;
// Run through all active TCP connections to locate TCP connection in question
for (int i = 0; i < tcpConnections->Length; i++)
{
if ((tcpConnections[i]->LocalEndPoint->Equals(localEndPoint)) && (tcpConnections[i]->RemoteEndPoint->Equals(remoteEndPoint)))
{
// Found active TCP connection in question
tcpState = tcpConnections[i]->State;
break;
}
}
}
}
return tcpState;
}
bool TcpConnected(TcpClient ^ tcpClient)
{
bool bTcpConnected = false;
if (tcpClient != nullptr)
{
if (GetTcpConnectionState(tcpClient) == TcpState::Established)
{
bTcpConnected = true;
}
}
return bTcpConnected;
}
希望这会对某人有所帮助 .
2 years ago
我创建了这个功能,并为我工作,检查客户端是否仍与服务器连接 .
///
/// THIS FUNCTION WILL CHECK IF CLIENT IS STILL CONNECTED WITH SERVER.
///
/// FALSE IF NOT CONNECTED ELSE TRUE
public bool isClientConnected()
{
IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
TcpConnectionInformation[] tcpConnections = ipProperties.GetActiveTcpConnections();
foreach (TcpConnectionInformation c in tcpConnections)
{
TcpState stateOfConnection = c.State;
if (c.LocalEndPoint.Equals(ClientSocket.Client.LocalEndPoint) && c.RemoteEndPoint.Equals(ClientSocket.Client.RemoteEndPoint))
{
if (stateOfConnection == TcpState.Established)
{
return true;
}
else
{
return false;
}
}
}
return false;
}
2 years ago
Peter Wone和uriel的解决方案非常好 . 但您还需要检查远程 endpoints ,因为您可以与本地 endpoints Build 多个打开的连接 .
public static TcpState GetState(this TcpClient tcpClient)
{
var foo = IPGlobalProperties.GetIPGlobalProperties()
.GetActiveTcpConnections()
.SingleOrDefault(x => x.LocalEndPoint.Equals(tcpClient.Client.LocalEndPoint)
&& x.RemoteEndPoint.Equals(tcpClient.Client.RemoteEndPoint)
);
return foo != null ? foo.State : TcpState.Unknown;
}
2 years ago
就我而言,我正在向服务器发送一些命令(在同一台计算机上的虚拟机中运行)并等待响应 . 但是,如果服务器在等待时意外停止,我没有收到任何通知 . 我尝试了其他海报提出的可能性,但都没有工作(它总是说服务器仍然连接) . 对我来说,唯一有效的是向流中写入0个字节:
var client = new TcpClient();
//... open the client
var stream = client.GetStream();
//... send something to the client
byte[] empty = { 0 };
//wait for response from server
while (client.Available == 0)
{
//throws a SocketException if the connection is closed by the server
stream.Write(empty, 0, 0);
Thread.Sleep(10);
}
2 years ago
试试这个,它对我有用
private void timer1_Tick(object sender, EventArgs e)
{
if (client.Client.Poll(0, SelectMode.SelectRead))
{
if (!client.Connected) sConnected = false;
else
{
byte[] b = new byte[1];
try
{
if (client.Client.Receive(b, SocketFlags.Peek) == 0)
{
// Client disconnected
sConnected = false;
}
}
catch { sConnected = false; }
}
}
if (!sConnected)
{
//--Basically what you want to do afterwards
timer1.Stop();
client.Close();
ReConnect();
}
}
我使用Timer因为,我想定期检查连接状态,而不是在带有听力代码的LOOP中[我觉得它减慢了发送 - 接收过程]