导航:首页 > IDC知识 > 服务器心跳包

服务器心跳包

发布时间:2020-12-06 18:13:15

1、服务器不能收到客户端的心跳包

不知这来个心跳包传输模式是广播源还是点到点呢
也许是交换机工作模式不匹配你的应用,二级交换可直接广播,三级交换会过滤广播的心跳包.需要三级交换配置下转发广播

检查几点,心跳包发包模式,网络互通,程序设置,交换机工作模式

2、服务端主动发送心跳包,还是客户端发送比较好

建议客户端发送心跳包较为合适,原因:
1、若用户较多,服务端专发送心跳包易使服务属器超负荷。
2、客户端发送请求数据时可视为一次心跳包发送,节约处理速度。
3、客户端发送失败可立刻选择自动退出,服务端发送需要给客户端设置一个较长的等待时间,响应异常情况速度变慢。
当然客户端发送容易被篡改数据等,此处需要根据实际情况考虑。

3、java的自动发送心跳包究竟是该写在服务器还是客户端

socket.setKeepAlive()应该写在客户端,server.accept()是服务器端的。

心跳的也有现成的,不过依赖别的类。大概贴一下,就是这么个意思。


public class HBHBThread extends Thread {
private CommandDeal command;
 
/**
 * @return the command
 */
public CommandDeal getCommand() {
return command;
}

/**
 * @param command
 *            the command to set
 */
public void setCommand(CommandDeal command) {
this.command = command;
}

public void run() {

long maxWait = SendConfig.hbhb_wait;
if (maxWait < 1000) {
maxWait = 1000;
}
Date lastTime;
long timeDiv=0;
while (1 == 1) {
 lastTime=SocketQueueObject.getLastContactTime();
 if(lastTime!=null){
 timeDiv=(new Date()).getTime() - SocketQueueObject.getLastContactTime().getTime();
 System.out.println("TimeDiv:"+timeDiv);
 }
// 上次联系的时间超过最大等待,或者还没联系过
if (lastTime == null|| timeDiv >=maxWait) {
System.out.println("HBHB"); 
command.sendHbhbCommand();
}else if(maxWait>timeDiv){
maxWait=maxWait-timeDiv;
}
try{
this.sleep(maxWait);
}catch(Exception e){
e.printStackTrace();
}
}
}public class HBHBCommandDeal extends CommandDealInterface {
private static Logger msg_logger = Logger.getLogger("socketMsg");

@SuppressWarnings("unchecked")
public List doCommand(SocketQueueObject socketQueueObject, Map command) throws Exception {
List<String> commandList = (List) command.get(Constants.SMSCOMMAND);
byte[] hbhbMsg = TL1Tool.createCommand(commandList.get(0));
msg_logger.info(" send message to sms packed:" + new String(hbhbMsg, "ISO-8859-1"));
TL1RetrunMessage retMsg = socketQueueObject.commNGNServer(hbhbMsg);
retMsg.resolve();
msg_logger.info(" recevice message from sms:"+ retMsg.getMessage()); 
List returnList = new ArrayList();
returnList.add(retMsg);
return returnList;
}
}

你可以自己找找看啊。

4、服务端主动发送心跳包,还是客户端发送比较好

一般是用来判断对方(设备,进程或其它网元)是否正常动行,一般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉。用于检测TCP的异常断开。一般是用来判断对方(设备,进程或其它网元)是否正常动行,一般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉。用于检测TCP的异常断开。基本原因是服务器端不能有效的判断客户端是否在线也就是说,服务器无法区分客户端是长时间在空闲,还是已经掉线的情况.所谓的心跳包就是客户端定时发送简单的信息给服务器端告诉它我还在而已。代码就是每隔几分钟发送一个固定信息给服务端,服务端收到后回复一个固定信息如果服务端几分钟内没有收到客户端信息则视客户端断开。比如有些通信软件长时间不使用,要想知道它的状态是在线还是离线就需要心跳包,定时发包收包。发包方:可以是客户也可以是服务端,看哪边实现方便合理。一般是客户端。服务器也可以定时轮询发心跳下去。一般来说,出于效率的考虑,是由客户端主动向服务器端发包,而不是就是在客户端和服务器间定时通知对方自己状态的一个自己定义的命令字,按照一定的时间间隔发送,类似于心跳,所以叫做心跳包。 就是定时发送给对方一个数据包,告诉对方自己还在维护对话,同时获得返回的数据,判断对方是否在会话中。客户端每隔一段时间发一个包,使用TCP的,用send发,使用UDP的,用sendto发,服务器收到后,就知道当前客户端还处于“活着”的状态,否则,如果隔一定时间未收到这样的包,则服务器认为客户端已经断开,进行相应的客户端断开逻辑处理。

5、android 心跳包服务器怎么写

[java] 
public class HeartbeatService extends Service implements Runnable  
{  
    private Thread          mThread;  
    public int              count           = 0;  
    private boolean         isTip           = true;  
    private static String   mRestMsg;  
    private static String   KEY_REST_MSG    = "KEY_REST_MSG";  
  
    @Override  
    public void run()  
    {  
        while (true)  
        {  
            try  
            {  
                if (count > 1)  
                {  
                    Log.i("@qi", "offline");  
                    count = 1;  
                    if (isTip)  
                    {  
                        //判断应用是否在运行   
                        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);  
                        List<RunningTaskInfo> list = am.getRunningTasks(3);  
                        for (RunningTaskInfo info : list)  
                        {  
                            if (info.topActivity.getPackageName().equals("org.yhn.demo"))  
                            {  
                                //通知应用,显示提示“连接不到服务器”   
                                Intent intent = new Intent("org.yhn.demo");  
                                intent.putExtra("msg", true);  
                                sendBroadcast(intent);  
                                break;  
                            }  
                        }  
  
                        isTip = false;  
                    }  
                }  
                if (mRestMsg != "" && mRestMsg != null)  
                {  
                    //向服务器发送心跳包   
                    sendHeartbeatPackage(mRestMsg);  
                    count += 1;  
                }  
  
                Thread.sleep(1000 * 3);  
            }  
            catch (InterruptedException e)  
            {  
                e.printStackTrace();  
            }  
        }  
    }  
  
    private void sendHeartbeatPackage(String msg)  
    {  
        HttpGet httpGet = new HttpGet(msg);  
        DefaultHttpClient httpClient = new DefaultHttpClient();  
        // 发送请求   
        HttpResponse httpResponse = null;  
        try  
        {  
            httpResponse = httpClient.execute(httpGet);  
        }  
        catch (Exception e)  
        {  
            e.printStackTrace();  
        }  
        if (httpResponse == null)  
        {  
            return;  
        }  
  
        // 处理返回结果   
        final int responseCode = httpResponse.getStatusLine().getStatusCode();  
        if (responseCode == HttpStatus.SC_OK)  
        {  
            //只要服务器有回应就OK   
            count = 0;  
            isTip = true;  
        }  
        else  
        {  
            Log.i("@qi", "responseCode " + responseCode);  
        }  
  
    }  
  
    @Override  
    public IBinder onBind(Intent intent)  
    {  
        return null;  
    }  
  
  
    @Override  
    public void onCreate()  
    {  
        super.onCreate();  
    }  
  
  
  
    @Override  
    public void onDestroy()  
    {  
        super.onDestroy();  
    }  
  
    public void onStart(Intent intent, int startId)  
    {  
        Log.i("@qi", "service onStart");  
        //从本地读取服务器的URL,如果没有就用传进来的URL   
        mRestMsg = getRestMsg();  
        if (mRestMsg == null || mRestMsg == "")  
        {  
            mRestMsg = intent.getExtras().getString("url");  
        }  
        setRestMsg(mRestMsg);  
  
        mThread = new Thread(this);  
        mThread.start();  
        count = 0;  
  
        super.onStart(intent, startId);  
    }  
  
    public String getRestMsg()  
    {  
        SharedPreferences prefer = getSharedPreferences("settings.data", Context.MODE_PRIVATE);  
        Log.i("@qi", "getRestMsg() " + prefer.getString(KEY_REST_MSG, ""));  
        return prefer.getString(KEY_REST_MSG, "");  
    }  
  
    public void setRestMsg(String restMsg)  
    {  
        SharedPreferences prefer = getSharedPreferences("settings.data", Context.MODE_PRIVATE);  
        SharedPreferences.Editor editor = prefer.edit();  
        editor.putString(KEY_REST_MSG, restMsg);  
        editor.commit();  
    }  
  
}  
 
public class HeartbeatService extends Service implements Runnable
{
private Thread mThread;
public int count = 0;
private boolean isTip = true;
private static String mRestMsg;
private static String KEY_REST_MSG = "KEY_REST_MSG";
 
@Override
public void run()
{
while (true)
{
try
{
if (count > 1)
{
Log.i("@qi", "offline");
count = 1;
if (isTip)
{
//判断应用是否在运行
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> list = am.getRunningTasks(3);
for (RunningTaskInfo info : list)
{
if (info.topActivity.getPackageName().equals("org.yhn.demo"))
{
//通知应用,显示提示“连接不到服务器”
Intent intent = new Intent("org.yhn.demo");
intent.putExtra("msg", true);
sendBroadcast(intent);
break;
}
}
 
isTip = false;
}
}
if (mRestMsg != "" && mRestMsg != null)
{
//向服务器发送心跳包
sendHeartbeatPackage(mRestMsg);
count += 1;
}
 
Thread.sleep(1000 * 3);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
 
private void sendHeartbeatPackage(String msg)
{
HttpGet httpGet = new HttpGet(msg);
DefaultHttpClient httpClient = new DefaultHttpClient();
// 发送请求
HttpResponse httpResponse = null;
try
{
httpResponse = httpClient.execute(httpGet);
}
catch (Exception e)
{
e.printStackTrace();
}
if (httpResponse == null)
{
return;
}
 
// 处理返回结果
final int responseCode = httpResponse.getStatusLine().getStatusCode();
if (responseCode == HttpStatus.SC_OK)
{
//只要服务器有回应就OK
count = 0;
isTip = true;
}
else
{
Log.i("@qi", "responseCode " + responseCode);
}
 
}
 
@Override
public IBinder onBind(Intent intent)
{
return null;
}
 
 
@Override
public void onCreate()
{
super.onCreate();
}
 
 
 
@Override
public void onDestroy()
{
super.onDestroy();
}
 
public void onStart(Intent intent, int startId)
{
Log.i("@qi", "service onStart");
//从本地读取服务器的URL,如果没有就用传进来的URL
mRestMsg = getRestMsg();
if (mRestMsg == null || mRestMsg == "")
{
mRestMsg = intent.getExtras().getString("url");
}
setRestMsg(mRestMsg);
 
mThread = new Thread(this);
mThread.start();
count = 0;
 
super.onStart(intent, startId);
}
 
public String getRestMsg()
{
SharedPreferences prefer = getSharedPreferences("settings.data", Context.MODE_PRIVATE);
Log.i("@qi", "getRestMsg() " + prefer.getString(KEY_REST_MSG, ""));
return prefer.getString(KEY_REST_MSG, "");
}
 
public void setRestMsg(String restMsg)
{
SharedPreferences prefer = getSharedPreferences("settings.data", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefer.edit();
editor.putString(KEY_REST_MSG, restMsg);
editor.commit();
}
 
}
 
 
启动Service:
 
 
[java]  
Intent serviceIntent = new Intent("HeartbeatService");  
serviceIntent.putExtra("url",url);  
startService(serviceIntent);  
 
Intent serviceIntent = new Intent("HeartbeatService");
serviceIntent.putExtra("url",url);
startService(serviceIntent);
 
 
 
 
最后别忘了注册Server和GET_TASKS
 
 
[html]  
<service  
            android:name=".demo.HeartbeatService"  
            android:label="QServer"  
            android:persistent="true" >  
            <intent-filter>  
                <action android:name="HeartbeatService" />  
            </intent-filter>  
        </service>  
 
<service
            android:name=".demo.HeartbeatService"
            android:label="QServer"
            android:persistent="true" >
            <intent-filter>
                <action android:name="HeartbeatService" />
            </intent-filter>
        </service>[html] view plaincopyprint?
<uses-permission android:name="android.permission.GET_TASKS" />  
 
<uses-permission android:name="android.permission.GET_TASKS" />

6、用了心跳包,客户端12秒已发送,服务器判断15秒超时,socket连接2-3分钟就异常掉线,哪的事?

给你点建议,把接受用户连接请求的线程和处理用户消息的线程分开给你个参考吧

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Data.OleDb;

namespace QQ服务器
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
             = false;
        }
        private Dictionary<string, Socket> Users = new Dictionary<string, Socket>();
        Socket ser;
        System.Windows.Forms.Timer t=new System.Windows.Forms.Timer();

        private void button1_Click(object sender, EventArgs e)
        {
            Thread a = new Thread(ser1);
            if (button1.Text == "启动")
            {
                IPEndPoint ip = new IPEndPoint(IPAddress.Parse(textBox1.Text), int.Parse(maskedTextBox2.Text));
                ser = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                ser.Bind(ip);
                ser.Listen(20);
                a.IsBackground = true;
                a.Start(ser);
                button1.Text = "停止";
                label2.Text = "状态:运行中";
                状态ToolStripMenuItem.Text = "状态:运行中";
                t.Interval = 100;
                t.Tick += new EventHandler(fresh);
                t.Start();
            }
            else
            {
                ser.Close();
                a.Abort();
                a.DisableComObjectEagerCleanup();
                label2.Text = "状态:未启用";
                button1.Text = "启动";
                状态ToolStripMenuItem.Text = "状态:未启用";
            }

        }//启动服务器

        private void ser1(object o)//用户端登陆监听
        {

            Socket listen, lis = (Socket)o;        
            while (true)
            {
                try
                {
                    listen = lis.Accept();
                    Thread a = new Thread(receive);
                    a.IsBackground = true;
                    a.Start(listen);
                }
                catch { }
            }
        }

        private void receive(object o)//接受处理用户登陆消息
        {
            string ss = "";//接受消息
            Socket newsocket = (Socket)o;
            byte[] bb = new byte[1024];
            while (true)
            {
                try
                {
                    bb = new byte[1024];
                    newsocket.Receive(bb, bb.Length, 0);
                }
                catch {  return; }
                ss = System.Text.Encoding.BigEndianUnicode.GetString(bb);
                if (ss.Contains("user@")) break;
            }
            //消息处理
            }
        }
       
        private void beat(object o)
        {
            client c =(client)o;
            while (true)
            {
                try
                {
                    byte[] bb = new byte[1024];
                    bb = Encoding.BigEndianUnicode.GetBytes("~");
                    c.Sock.Send(bb, bb.Length, 0);
                    Thread.Sleep(500);
                }
                catch
                {
                    Users.Remove(c.User);
                    string sql = "update [users] set [状态] ='离线'where 帐号='" + c.User + "'";
                    updata(sql);
                    break;
                }
            }                
        }//心跳包

        class client
        {
            string user = null;
            Socket sock = null;
            public string User
            { 
            get{ return user;}
                set{ user=value;}

            }
            public Socket Sock
            {
                get { return sock; }
                set { sock = value; }
            }

        }//客户类

        
        public class userInf
        {
            string user = null,calls=null;
            public string User
            {
                get { return user; }
                set { user = value; }
            }
            public string Calls
            {
                get { return calls; }
                set { calls = value; }
            }
        
        }
        
        #endregion
}

7、如何向服务器发送心跳包

这个你要和服务器端协商接口 然后在ios这边用线程或者nstimer来调用发送心跳的接口
/向服务器发送心跳包 sendHeartbeatPackage(mRestMsg); count += 1; } Thread.sleep(1000 * 3); } catch (InterruptedException e)

8、服务器怎么判断心跳包?

用sendUrgentData这个来判断服务端是否异常关闭

想实现自动连接服务端,如果用
socket = new Socket("192.168.1.4",1821);
socket.connect();

只有每次去new创建这个sock对象,因为只有sock对象创建好了才由输入输出流

目前的实现方式就是,

1.在原有的基础上,再开多一个线程,专门负责发送心跳,

2.先睡眠500毫秒,

3.用socket.sendUrgentData(FF),给服务端,

4.如果服务端异常关闭的话,我就捕捉这个异常。。。

5.循环

心跳的意思就是每隔一段时间,客户端给服务器发一段消息:
1、客户端:服务器,我还活着,你死了没
2、服务器:客户端,我知道你还活着这个信息,我已经记录下来了,同时告诉你我也还活着

更多问题到问题求助专区http://bbs.hounwang.com/

与服务器心跳包相关的知识