1. 程式人生 > >C# 網路連線中異常斷線的處理:ReceiveTimeout, SendTimeout 及 KeepAliveValues(設定心跳)

C# 網路連線中異常斷線的處理:ReceiveTimeout, SendTimeout 及 KeepAliveValues(設定心跳)

在使用 TcpClient 網路連線中常常會發生客戶端連線異常斷開, 服務端需要設定檢測手段進行這種異常的處理.

   對於短連線, 通過對 Socket 屬性 ReceiveTimeout 和 SendTimeout 設定適當的值, 當在進行讀/寫時超時, 則會產生 SocketException 異常, 通過檢查這個異常並進行處理. 如下服務端連線處理程式碼示例:

                while (newClient.Connected && isConnected)
                {
                    ns.ReadTimeout

 = 60000; // frist, 60s
                    newClient.Client.SendTimeout = 1000;
                    int bytesRead = 0;
                    try
                    {
                        bytesRead = ns.Read(buffer, 0, buffer.Length); // 讀取資料, 根據內容進行回覆
                        if (bytesRead == 1)
                        {
                            //string receiveInfo = Encoding.ASCII.GetString(buffer, 0, bytesRead);
                            CmdType cmd = (CmdType)buffer[0];

                            connect.ReceiveInfo = cmd.ToString(); // 儲存儲存的資訊
                            if (ReceiveData != null)
                            {
                                EventArgs e = new EventArgs();
                                ReceiveData(this, e);
                            }

                            ns.ReadTimeout = 1000; // decrease to 1s

                            //響應請求 response
                            string response = "hello";
                            buffer = Encoding.UTF8.GetBytes(String.Format("[{0:d4}] {1}", id, response));
                            ns.Write(buffer, 0, buffer.Length);

                        }

                        Thread.Sleep(100);
                    }
                    catch
                    {
                        bytesRead = 0;
                        isConnected = false; // 異常則立即終止連線
                    }
                }

            newClient.Close();

         對於長連線可以通過 Socket 中的心跳檢測機制進行處理.

         Socket的底層IO一般通過 WSAIoctl 函式進行設定. C# 中對此函式進行了封裝, 即 Socket.IOControl 方法.

public int IOControl(
	IOControlCode ioControlCode,
	byte[] optionInValue,
	byte[] optionOutValue
)
其中第一個引數為 Socket IO 控制程式碼; 第二個引數為傳入引數值, 第三個引數為傳出值.
Winsock 2 中定義了許多 Socket IO 控制型別 , 其中有一項: KeepAliveValues , 控制 TCP keep-alive 資料包的傳送以及傳送間隔。預設值為2個小時, 當間隔時間超過這個設定後, socket就會連續傳送5次連線訊號, 若客戶端無迴應, 則此 client socket會斷開.
我們可以如下調整這個間隔時間:
newClient.Client.IOControl(IOControlCode.KeepAliveValues, BitConverter.GetBytes(120), null); // 設定為 2分鐘.
以上即為2種網路異常連線斷線檢測的方法.