導航:首頁 > 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/

與伺服器心跳包相關的知識