歡迎您的來訪!有源碼,好建站(m.bmm520.net)源碼海洋源碼網為您提供快速建站平臺.
      當前位置: 首頁 > 行業資訊 > c# .net 資料 >

      c# socket 斷線重連

      時間:2021-07-11 23:42來源:未知 作者:admin 點擊:
      https://blog.csdn.net/thebestleo/article/details/52354126 里面有socket的封裝類 但是沒有使用的代碼,在這里補充一下 服務器端主動斷開連接,客戶端會拋出異常,并會設置連接狀態 IsconnectSuccess 為false,但不會自動重連,所以加了一個timer Socket_w

       https://blog.csdn.net/thebestleo/article/details/52354126

       
      里面有socket的封裝類
       
      但是沒有使用的代碼,在這里補充一下
       
      服務器端主動斷開連接,客戶端會拋出異常,并會設置連接狀態 IsconnectSuccess 為false,但不會自動重連,所以加了一個timer
      Socket_wrapper.remoteHost="127.0.0.1";
                  Socket_wrapper.remotePort = 9601;
                  Socket_wrapper.checkSocketState();
       
                  timer = new Timer();
                  timer.Interval = 30 * 1000;
                  timer.Tick += Timer_Tick;
                  timer.Start();
      • private void Timer_Tick(object sender, EventArgs e)
      •  
        {
      •  
        Socket_wrapper.checkSocketState();
      •  
        }

        補充:之前為啥沒有寫 接收服務器端的方法,現在補上

        socket封裝類,socket換成TcpClient  

        1.  
        2. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Sockets; using System.Net; using System.Threading; using System.Runtime.InteropServices; namespace TcpDisconnectDemo { public class Socket_wrapper { //委托 public delegate void delSocketDataArrival(byte[] data); public static delSocketDataArrival socketDataArrival = socketDataArrivalHandler; public delegate void delSocketDisconnected(); public static delSocketDisconnected socketDisconnected = socketDisconnectedHandler; public static TcpClient theSocket = null; private static string remoteHost = "192.168.1.71"; private static int remotePort = 6666; private static String SockErrorStr = null; private static ManualResetEvent TimeoutObject = new ManualResetEvent(false); private static Boolean IsconnectSuccess = false; //異步連接情況,由異步連接回調函數置位 private static object lockObj_IsConnectSuccess = new object(); /// /// 構造函數 /// /// /// public Socket_wrapper(string strIp, int iPort) { remoteHost = strIp; remotePort = iPort; } private static byte[] KeepAliveTime { get { uint dummy = 0; byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3]; BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0); BitConverter.GetBytes((uint)5000).CopyTo(inOptionValues, Marshal.SizeOf(dummy)); BitConverter.GetBytes((uint)5000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2); return inOptionValues; } } /// /// 設置心跳 /// private static void SetXinTiao() { //byte[] inValue = new byte[] { 1, 0, 0, 0, 0x20, 0x4e, 0, 0, 0xd0, 0x07, 0, 0 };// 首次探測時間20 秒, 間隔偵測時間2 秒 byte[] inValue = new byte[] { 1, 0, 0, 0, 0x88, 0x13, 0, 0, 0xd0, 0x07, 0, 0 };// 首次探測時間5 秒, 間隔偵測時間2 秒 theSocket.Client.IOControl(IOControlCode.KeepAliveValues, KeepAliveTime, null); } /// /// 創建套接字+異步連接函數 /// /// private static bool socket_create_connect() { IPAddress ipAddress = IPAddress.Parse(remoteHost); IPEndPoint remoteEP = new IPEndPoint(ipAddress, remotePort); theSocket = new TcpClient(); theSocket.SendTimeout = 1000; SetXinTiao();//設置心跳參數 #region 異步連接代碼 TimeoutObject.Reset(); //復位timeout事件 try { theSocket.BeginConnect(ipAddress,remotePort, connectedCallback, theSocket); } catch (Exception err) { SockErrorStr = err.ToString(); return false; } if (TimeoutObject.WaitOne(10000, false))//直到timeout,或者TimeoutObject.set() { if (IsconnectSuccess) { return true; } else { return false; } } else { SockErrorStr = "Time Out"; return false; } #endregion } /// /// 同步receive函數 /// /// /// public string socket_receive(byte[] readBuffer) { try { if (theSocket == null) { socket_create_connect(); } else if (!theSocket.Connected) { if (!IsSocketConnected()) Reconnect(); } int bytesRec = theSocket.Client.Receive(readBuffer); if (bytesRec == 0) { //warning 0 bytes received } return Encoding.ASCII.GetString(readBuffer, 0, bytesRec); } catch (SocketException se) { //print se.ErrorCode throw; } } /// /// 同步send函數 /// /// /// public bool socket_send(string sendMessage) { if (checkSocketState()) { return SendData(sendMessage); } return false; } /// /// 斷線重連函數 /// /// private static bool Reconnect() { //關閉socket theSocket.Client.Shutdown(SocketShutdown.Both); theSocket.Client.Disconnect(true); IsconnectSuccess = false; theSocket.Close(); //創建socket return socket_create_connect(); } /// /// 當socket.connected為false時,進一步確定下當前連接狀態 /// /// private bool IsSocketConnected() { #region remarks /******************************************************************************************** * 當Socket.Conneted為false時, 如果您需要確定連接的當前狀態,請進行非阻塞、零字節的 Send 調用。 * 如果該調用成功返回或引發 WAEWOULDBLOCK 錯誤代碼 (10035),則該套接字仍然處于連接狀態; * 否則,該套接字不再處于連接狀態。 * Depending on http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.connected.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2 ********************************************************************************************/ #endregion #region 過程 // This is how you can determine whether a socket is still connected. bool connectState = true; bool blockingState = theSocket.Client.Blocking; try { byte[] tmp = new byte[1]; theSocket.Client.Blocking = false; theSocket.Client.Send(tmp, 0, 0); //Console.WriteLine("Connected!"); connectState = true; //若Send錯誤會跳去執行catch體,而不會執行其try體里其之后的代碼 } catch (SocketException e) { // 10035 == WSAEWOULDBLOCK if (e.NativeErrorCode.Equals(10035)) { //Console.WriteLine("Still Connected, but the Send would block"); connectState = true; } else { //Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode); connectState = false; } } finally { theSocket.Client.Blocking = blockingState; } //Console.WriteLine("Connected: {0}", client.Connected); return connectState; #endregion } /// /// 另一種判斷connected的方法,但未檢測對端網線斷開或ungraceful的情況 /// /// /// public static bool IsSocketConnected(Socket s) { #region remarks /* As zendar wrote, it is nice to use the Socket.Poll and Socket.Available, but you need to take into consideration * that the socket might not have been initialized in the first place. * This is the last (I believe) piece of information and it is supplied by the Socket.Connected property. * The revised version of the method would looks something like this: * from:http://stackoverflow.com/questions/2661764/how-to-check-if-a-socket-is-connected-disconnected-in-c */ #endregion #region 過程 if (s == null) return false; return !((s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0)) || !s.Connected); /* The long, but simpler-to-understand version: bool part1 = s.Poll(1000, SelectMode.SelectRead); bool part2 = (s.Available == 0); if ((part1 && part2 ) || !s.Connected) return false; else return true; */ #endregion } /// /// 異步連接回調函數 /// /// static void connectedCallback(IAsyncResult iar) { #region <remarks> /// 1、置位IsconnectSuccess #endregion </remarks> lock (lockObj_IsConnectSuccess) { TcpClient client = (TcpClient)iar.AsyncState; try { client.EndConnect(iar); IsconnectSuccess = true; StartKeepAlive(); //開始KeppAlive檢測 } catch (Exception e) { //Console.WriteLine(e.ToString()); SockErrorStr = e.ToString(); IsconnectSuccess = false; } finally { TimeoutObject.Set(); } } } /// /// 開始KeepAlive檢測函數 /// private static void StartKeepAlive() { theSocket.Client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveCallback), theSocket); } /// /// BeginReceive回調函數 /// static byte[] buffer = new byte[1024]; private static void OnReceiveCallback(IAsyncResult ar) { try { TcpClient peerSock = (TcpClient)ar.AsyncState; int BytesRead = peerSock.Client.EndReceive(ar); if (BytesRead > 0) { byte[] tmp = new byte[BytesRead]; Array.ConstrainedCopy(buffer, 0, tmp, 0, BytesRead); if (socketDataArrival != null) { socketDataArrival(tmp); } } else//對端gracefully關閉一個連接 { if (theSocket.Connected)//上次socket的狀態 { if (socketDisconnected != null) { //1-重連 socketDisconnected(); //2-退出,不再執行BeginReceive return; } } } //此處buffer似乎要清空--待實現 zq theSocket.Client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveCallback), theSocket); } catch (Exception ex) { if (socketDisconnected != null) { socketDisconnected(); //Keepalive檢測網線斷開引發的異常在這里捕獲 return; } } } /// /// 異步收到消息處理器 /// /// private static void socketDataArrivalHandler(byte[] data) { } /// /// socket由于連接中斷(軟/硬中斷)的后續工作處理器 /// private static void socketDisconnectedHandler() { Reconnect(); } /// /// 檢測socket的狀態 /// /// public static bool checkSocketState() { try { if (theSocket == null) { return socket_create_connect(); } else if (IsconnectSuccess) { return true; } else//已創建套接字,但未connected { #region 異步連接代碼 TimeoutObject.Reset(); //復位timeout事件 try { IPAddress ipAddress = IPAddress.Parse(remoteHost); IPEndPoint remoteEP = new IPEndPoint(ipAddress, remotePort); theSocket.Client.BeginConnect(remoteEP, connectedCallback, theSocket); SetXinTiao();//設置心跳參數 } catch (Exception err) { SockErrorStr = err.ToString(); return false; } if (TimeoutObject.WaitOne(2000, false))//直到timeout,或者TimeoutObject.set() { if (IsconnectSuccess) { return true; } else { return false; } } else { SockErrorStr = "Time Out"; return false; } #endregion } } catch (SocketException se) { SockErrorStr = se.ToString(); return false; } } /// /// 同步發送 /// /// /// public static bool SendData(string dataStr) { bool result = false; if (dataStr == null || dataStr.Length < 0) return result; try { byte[] cmd = Encoding.Default.GetBytes(dataStr); int n = theSocket.Client.Send(cmd); if (n < 1) result = false; } catch (Exception ee) { SockErrorStr = ee.ToString(); result = false; } return result; } } } 程序調用
        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; using System.Threading.Tasks; using System.Windows.Forms; namespace TcpDisconnectDemo { public partial class Form1 : Form { public Form1() { InitializeComponent(); } Socket_wrapper ssw; System.Windows.Forms.Timer timer; private void Form1_Load(object sender, EventArgs e) { ssw = new Socket_wrapper("192.168.83.129", 10000); Socket_wrapper.socketDataArrival = Socket_wrapper_socketDataArrival; Socket_wrapper.checkSocketState(); timer = new System.Windows.Forms.Timer(); timer.Interval = 10 * 1000; timer.Tick += Timer_Tick; timer.Start(); } private delegate void SetLabelDelegate(string value); private void SetText(string value) { if (this.InvokeRequired) { SetLabelDelegate d = new SetLabelDelegate(SetText); this.Invoke(d, new object[] { value }); } else { textBox1.Text = value.ToString(); } } private void Socket_wrapper_socketDataArrival(byte[] data) { string ss = Encoding.ASCII.GetString(data, 0, data.Length); //Console.WriteLine(ss); SetText(ss); } private void Timer_Tick(object sender, EventArgs e) { Socket_wrapper.checkSocketState(); } } }
           
      (責任編輯:admin)本文地址:http://m.bmm520.net/info/net/2021/0711/22473.html

      推薦資訊

      亚洲成aⅴ人片在线影院八| 亚洲国产精品专区在线观看| 亚洲国产成人九九综合| 亚洲精品无码成人片在线观看| 亚洲av无码兔费综合| 亚洲精品无码久久久久sm| 亚洲天堂2016| 亚洲va久久久噜噜噜久久男同| 亚洲欧美一区二区三区日产| 亚洲精品免费在线观看| 亚洲av无码国产精品色在线看不卡 | 亚洲人JIZZ日本人| 亚洲乱妇老熟女爽到高潮的片 | 夜夜春亚洲嫩草影院| 亚洲欧洲AV无码专区| 亚洲精品无码久久久久秋霞| 亚洲高清免费在线观看| 在线亚洲人成电影网站色www| 337p日本欧洲亚洲大胆裸体艺术| 国产成人亚洲精品狼色在线| 亚洲VA中文字幕不卡无码| 亚洲国产高清人在线| 亚洲理论精品午夜电影| 亚洲精品第一综合99久久| 亚洲精品午夜在线观看| 亚洲国产精品福利片在线观看| 亚洲精品成人片在线观看| 国产亚洲精品成人AA片新蒲金| 亚洲午夜国产精品无码| 久久91亚洲精品中文字幕| 亚洲日韩一页精品发布| 水蜜桃亚洲一二三四在线| 亚洲的天堂av无码| 中文字幕亚洲综合久久综合| 亚洲黄色在线播放| 亚洲乱码一区二区三区国产精品| 亚洲精品蜜夜内射| 亚洲视频一区二区| 亚洲国产成人久久综合碰| 亚洲一区二区三区无码中文字幕 | 亚洲国产精品网站在线播放|