c与java tcpclient连接_如何检查TcpClient连接是否已关闭?

回答(7)

e15298c6a3b4591803e154ab0c3b3e2e.png

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;

}

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

据我所知/记得没有办法测试套接字是否连接而不是读取或写入 .

我根本没有使用过TcpClient,但是如果远程端已正常关闭,Socket类将从调用Read返回0 . 如果远程端没有正常关闭[我认为]你得到超时异常,不记得抱歉的类型 .

使用像' if(socket.Connected) { socket.Write(...) } 这样的代码会产生竞争条件 . 你最好只是调用socket.Write并处理异常和/或断开连接 .

e15298c6a3b4591803e154ab0c3b3e2e.png

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;

}

希望这会对某人有所帮助 .

e15298c6a3b4591803e154ab0c3b3e2e.png

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;

}

e15298c6a3b4591803e154ab0c3b3e2e.png

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;

}

e15298c6a3b4591803e154ab0c3b3e2e.png

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);

}

e15298c6a3b4591803e154ab0c3b3e2e.png

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中[我觉得它减慢了发送 - 接收过程]

在C#中,使用TcpClient连接网络时,可以通过设置TcpClient的Socket属性来配置连接超时。连接超时通常用于指定在尝试连接到远程主机时允许的等待时间。如果在该时间范围内无法建立连接,则会抛出一个异常。以下是如何设置连接超时的步骤: 1. 创建TcpClient实例。 2. 获取TcpClient关联的Socket对象。 3. 使用Socket对象的`ConnectTimeout`属性来设置超时时间(单位为毫秒)。 4. 调用TcpClient的`Connect`方法尝试连接到远程主机。 请注意,由于Socket的`Connect`方法是同步的,所以当超时发生时,它会抛出一个`SocketException`异常。为了避免阻塞主线程,建议在后台线程中执行连接操作。 示例代码如下: ```csharp using System; using System.Net.Sockets; using System.Threading; public class TcpClientExample { public void ConnectToServer(string host, int port, int timeout) { TcpClient client = new TcpClient(); try { // 设置超时时间 client.Client.ReceiveTimeout = timeout; client.Client.SendTimeout = timeout; // 尝试连接到服务器 client.Connect(host, port); // 连接成功后的操作 Console.WriteLine("连接成功!"); // ... 进行数据交互等操作 ... } catch (SocketException ex) { // 处理连接超时或连接错误 Console.WriteLine("连接服务器失败: " + ex.Message); } finally { client.Close(); } } } class Program { static void Main() { TcpClientExample example = new TcpClientExample(); // 假设连接超时设置为5000毫秒(即5秒) example.ConnectToServer("127.0.0.1", 12345, 5000); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值