作者:faaronzheng 转载请注明出处!
背景是这样的,在之前一个客户端服务器的项目中服务器端需要根据客户端发送的报文来判断客户端是否还在线。于是乎采用心跳程序定时向服务器发送一个报文来解决这个问题。
客户端:
void UdpSendThread()
{
String msg = “client+”+info.user_id.ToString(); //发送内容
UdpClient uc = new UdpClient();
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(“xxx.xx.xx.xxx”), int.Parse(“xxxxx”)); //服务端ip地址和端口
while (true)
{
try
{
byte[] sendbuf = Encoding.UTF8.GetBytes(msg);
uc.Send(sendbuf, sendbuf.Length, remoteEndPoint); //发送
}
catch (Exception ex)
{
MessageBox.Show("连接服务器失败!");
Application.Exit();
}
Thread.Sleep(30000);
}
}
客户端在一个线程中每隔一段时间向服务端发送一个报文。报文的内容是client+id。
服务端:
public void UdpReciveheartbeatThread()
{
IPEndPoint remoteHost = null;
listener = new UdpClient(port2); //监听指定端口
//user u = new user();
//u.listener = listener;
while (true)
{
if (flag)
{
try
{
// listBox1.Items.Clear();
byte[] buf = listener.Receive(ref remoteHost); //获取收到的报文
//a = DateTime.Now.Ticks;
//u.a = a;
string bufs = Encoding.UTF8.GetString(buf);
String[] msg = bufs.Split('+');
if (msg[0] == "client")
{
onhook[Convert.ToInt32(msg[1])] = 1; //记录客户端状态的数组
}
if (msg[1] == "control")
{
control[Convert.ToInt32(msg[1])] = 1;
}
}
catch (Exception e)
{
label1.Text = e.Message;
label2.Text = e.Source;
}
}
else
{
return;
}
}
}
服务端在一个循环中一直等待客户端的报文,客户端报文到达后记录下client的id。在记录客户端活跃状态的onhook数组中相应的位置1,表示最近收到过这个id的报文。这样服务器端就有了客户端活跃的记录。服务器端只要定时将onhook数组清零。在等待一个“心跳时间”后就可以知道哪些客户端是活跃的,哪些是不活跃的。
而对于具体的清零时间和心跳时间则可以根据自己的实际需求来设置。