- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在尝试让我的服务器应用程序在我的客户端断开连接时在标签中显示一条消息。
此时标签在客户端启动时会显示已连接客户端的IP地址,但当客户端关闭时,IP地址仍会显示在标签中。
到目前为止,我已经尝试过这些方法但没有任何运气:
// DETECT IF CLIENT DISCONNECTED
//METHOD 1
if (bytesRead == 0)
{
ClientIPLabel.Text = "(No Clients Connected)";
break;
}
//METHOD 2
if (!tcpListener.Pending())
{
ClientIPLabel.Text = "(No Clients Connected)";
}
//METHOD 3
if (tcpClient.Client.Poll(0, SelectMode.SelectRead))
{
byte[] buff = new byte[1];
if (tcpClient.Client.Receive(buff, SocketFlags.Peek) == 0)
{
ClientIPLabel.Text = "(No Clients Connected)";
}
我确定这可能是我遗漏的一些简单的东西,我只是不知道它可能是什么。
编辑:我发现了一些解决方法,当我单击关闭客户端应用程序的按钮时,客户端会在关闭前向服务器发送一条消息。服务器知道,如果它收到此特定消息(在本例中为“SHUTDOWN CLIENT”),则将“ClientIPLabel.text”中的文本更改为“(未连接客户端)”
这在大多数情况下确实有效,但它有点像 hack,如果客户端由于错误或崩溃等原因关闭。服务器不知道它已断开连接,因此它仍会显示最后已知的已发送 IP。
第二次编辑: 所以看来解决方法对我不起作用。将其添加到我的项目后,出于某种原因,无论我的客户端向服务器发送什么消息都会导致显示“(未连接客户端)”消息。
我的客户端实际上仍处于连接状态并接收消息,但“ClientIPLabel”标记不正确
第三次编辑:这是一个片段,显示了我如何设置我的客户端以按照我在下面的一条评论中详细说明的方式将消息发送到服务器:
private void SendMessage(string msg)
{
NetworkStream clientStream = ConsoleClient.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes(msg);
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
}
第四次编辑:我的服务器代码,以及我直接从客户端关闭按钮获取客户端断开连接消息的临时解决方法:
public partial class Server : Form
{
private TcpListener tcpListener;
private Thread listenThread;
private delegate void WriteMessageDelegate(string msg);
public Server()
{
InitializeComponent();
Server();
}
// WAIT FOR CLIENT
private void Server()
{
this.tcpListener = new TcpListener(IPAddress.Any, 8888);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
this.tcpListener.Start();
// GET CLIENT IP ADDRESS
while (true)
{
TcpClient client = this.tcpListener.AcceptTcpClient();
string clientIPAddress = "" + IPAddress.Parse(((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString());
ClientIPLabel.Text = clientIPAddress;
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
// COMMUNICATE WITH CLIENT
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
bytesRead = 0;
try
{
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
break;
}
ASCIIEncoding encoder = new ASCIIEncoding();
// CHECK FOR CLIENT DISCONNECT
string msg = encoder.GetString(message, 0, bytesRead);
WriteMessage(msg);
if (msg.Equals("Client Disconnected (" + DateTime.Now + ")"))
{
ClientIPLabel.Text = ("(No Client Connected)");
}
}
tcpClient.Close();
}
第 5 次编辑: 我已经更新了我的代码,并且(几乎)实现了心跳定时器,但它仍然没有完全正确地设置......这是我的代码:
// CHECK FOR CLIENT DISCONNECT
// SHUTDOWN BUTTON PRESSED
string msg = encoder.GetString(message, 0, bytesRead);
WriteMessage(msg);
if (msg.Equals("Client Disconnected (" + DateTime.Now + ")"))
{
ClientIPLabel.Text = ("(No Client Connected)");
}
}
tcpClient.Close();
}
// CHECK FOR CONNECTION FAILED
void heartbeatTimer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
HandleClientComm("Check for connection");
}
catch (Exception)
{
Invoke((MethodInvoker)delegate
{
ClientIPLabel.Text = "(No Clients Connected)";
});
}
}
“(无客户端连接)”消息在计时器后自动弹出到我的服务器上,无论我的客户端是否已断开连接,因此它没有正确捕获异常。
我已经尝试实现 interceptwind 的建议,因为他写了它,但出于某种原因,我应该有 catch (Exception e)
我只有在摆脱 e
写成catch (Exception)
。如果我将 e
留在那里,我会收到一条警告,提示 “变量 'e' 已声明但从未使用过”
。
此外,我知道 interceptwind 编写他的示例是为了使用我的 SendMessage() 方法,但该方法只在我的客户端中使用,所以我更改了代码以尝试使用我的 HandleClientComm() 方法,所以我想知道是否这就是无法正常工作的原因。我试过改变一些东西,但似乎仍然无法正常工作。 5 秒后我仍然收到消息“(没有客户端连接)”,即使我的客户端仍然连接并正常运行。
第 6 次编辑: 我试图调整我的 HandleClientComm()
方法来发送消息,但我显然错过了一些东西,因为我的“心跳计时器“仍在将我的 ClientIPLabel.text 切换为“(未连接客户端)”,即使我的客户端仍处于连接状态。
这是我的代码:
// COMMUNICATE WITH CLIENT
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] message = new byte[4096];
byte[] buffer = encoder.GetBytes("Send Message");
int bytesRead;
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
while (true)
{
bytesRead = 0;
try
{
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
break;
}
// START HEARTBEAT TIMER
System.Timers.Timer heartbeatTimer = new System.Timers.Timer();
heartbeatTimer.Interval = 5000;
heartbeatTimer.Elapsed += heartbeatTimer_Elapsed;
heartbeatTimer.Start();
// CHECK FOR CLIENT DISCONNECT
// SHUTDOWN BUTTON PRESSED
string msg = encoder.GetString(message, 0, bytesRead);
WriteMessage(msg);
if (msg.Equals("Client Disconnected (" + DateTime.Now + ")"))
{
ClientIPLabel.Text = ("(No Client Connected)");
}
}
tcpClient.Close();
}
// CHECK FOR CONNECTION FAILED
void heartbeatTimer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
HandleClientComm("Check for connection");
}
catch (Exception)
{
Invoke((MethodInvoker)delegate
{
ClientIPLabel.Text = "(No Clients Connected)";
});
}
}
最佳答案
鉴于OP限制Server不能向Client发送消息,另一种方式是Client每X秒(例如5秒)向Server发送一次心跳消息。
然后服务器将检查它是否在过去的 Y 秒(例如 30 秒)内收到了来自客户端的任何消息。如果没有,则意味着客户端已断开连接。
客户代码
public Client()
{
...
//After connection, CALL ONCE ONLY
Timer heartbeatTimer = new System.Timers.Timer();
heartbeatTimer.Interval = 5000; //5 seconds
heartbeatTimer.Elapsed += heartbeatTimer_Elapsed;
heartbeatTimer.Start();
}
void heartbeatTimer_Elapsed(object sender, ElapsedEventArgs e)
{
SendMessage("Heartbeat");
}
服务器代码
bool receiveHeartBeat = false;
public Server()
{
...
//After connection, CALL ONCE ONLY
Timer checkHeartbeatTimer = new System.Timers.Timer();
checkHeartbeatTimer.Interval = 30000; //30 seconds
checkHeartbeatTimer.Elapsed += checkHeartbeatTimer_Elapsed;
checkHeartbeatTimer.Start();
}
void checkHeartbeatTimer_Elapsed(object sender, ElapsedEventArgs e)
{
if(receiveHeartBeat)
{
Invoke((MethodInvoker)delegate //prevent cross-thread exception
{
ClientIPLabel.Text = "Connected";
});
}
else
{
Invoke((MethodInvoker)delegate //prevent cross-thread exception
{
ClientIPLabel.Text = "(No Clients Connected)";
});
}
}
void WriteMessage(string msg)
{
receiveHeartBeat = true;
// rest of your code
}
关于c# - 当 TCPClient 断开连接时显示消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34456104/
是否可以在蓝牙设备连接到 iOS 或从 iOS 断开连接时收到通知,即使我的应用程序处于后台?在 Android 上,我使用 ACTION_ACL_CONNECTED 和 ACTION_ACL_DIS
我对使用 Delphi 使用 USB 设备感到不舒服,并且对编写设备驱动程序的细节几乎一无所知(尽管我在学习使用 GoASM 进行汇编时遇到过一些)。 该设备可以是 USB 调制解调器或 USB 打印
我正在使用 java/servlet 和前端 JSP 开发 Web 应用程序。 我的页面为用户显示一些信息。 是否有任何适当的方法来检查网络连接是否处于 Activity 状态(开/关)以及支持所有浏
这个问题在这里已经有了答案: C# -- TcpListener.Start() causing SocketException with message "Only one usage of ea
我想向我的应用程序添加功能,以允许在 Windows 操作系统上检测播放/捕获设备的到达和断开连接。就像在 Skype 中一样 - 当您拔下设备时 - 它会显示设备丢失的通知,例如要求您选择另一个。
如何断开 org. apache. http. client.HttpClient 对象? 我正在这样创建它,但它没有任何 disconnect() 或 getHttpConnectionManage
我们正在开发一个 .NET 应用程序,其中一个要求是监视系统是否连接到 Internet。 我们能够获得“以太网电缆断开连接”的 .NET 事件,但如果调制解调器被重置,则不会触发此事件。我不想一直通
我正在尝试与使用自签名证书的后端服务器建立 websocket 连接。在 Firefox 中,我为自签名证书添加了一个异常(exception)。 但是我的 websocket 连接 wss://连接
我正在使用由 Excel 生成的用户窗体来修改 PowerPoint 演示文稿(这是避免需要启用宏的电子表格的迂回方法)。该表单工作得很好,但每次我将焦点放在它上时,Excel 应用程序都会获得焦点(
您好,我成功地开始了视频通话,但是当我断开视频通话时,摄像头 LED 指示灯仍然亮着。我怎样才能完全断开通话? Video.createLocalVideoTrack().then(track =>
您好,我成功地开始了视频通话,但是当我断开视频通话时,摄像头 LED 指示灯仍然亮着。我怎样才能完全断开通话? Video.createLocalVideoTrack().then(track =>
我正在尝试断开客户端与服务器的连接,但服务器仍将其视为已连接。我找不到解决这个问题的方法,关机、断开连接和关闭都不起作用。 我与客户端断开连接并检查服务器的一些代码: 客户: private vo
我正在使用 magic record 来完成我所有的核心数据工作。 一切都很好,除了有时我在后台进行更新时我需要从上下文中分离或断开实体。 例如 ButtonList = [Buttons MR_fi
我正在尝试实现一个颜色选择器,它从屏幕上各处的像素中获取颜色。为此,我计划使用全局鼠标 Hook 来监听 WM_MOUSEMOVE,以便在鼠标四处移动时更新颜色,并监听鼠标点击以确认 (WM_LBUT
我有一个使用 C# 编写的 TLS 连接的客户端/服务器 TCP 场景。 客户端在安静并恢复后无法传递消息(不活动时间约为 25 分钟)。但如果我让客户聊天(每 30 秒),就没有问题。 客户端和服务
我编写的这段代码完美运行,但我担心每 2 秒执行一次 ping 操作会消耗太多资源,或者可能导致互联网连接出现一些问题。 new Thread(() => {
关闭带有附加 MediaPlayer 的 MediaController 的正确方法是什么? 您不能执行 mediaController.setMediaPlayer(null) - 立即调用 upd
从我的笔记本电脑上断开外接显示器后,我丢失了一些应用程序,因为断开连接的显示器仍设置为默认显示器。我的一些窗口试图在断开连接的显示器上显示。 我有一个解决方法,例如右键单击应用程序图标并选择移动,然后
是否可以将分片节点从分片集中取出并独立运行? 例如,每个分片都有一个特定的客户。 谢谢。 最佳答案 是的,这是可能的。 MongoDB“主”节点不知道分片。只有路由器(和配置服务器)知道。如果您使用正
我正在探索 Cassandra 及其复制系统。为此,我在本地创建了 3 个节点并测试了不同的场景。我想暂停节点之间的通信,用相同的键写入不同的值,然后观察它们将决定什么。 那么问题来了:如何限制节点在
我是一名优秀的程序员,十分优秀!