1. 程式人生 > >C# + Socket斷線重連 整理

C# + Socket斷線重連 整理

1.如果是採用TCP/udp協議進行連線,檢查windows防火牆是否開放相應SocketTCP/udp埠;
  簡單的檢測方法是關閉windows防火牆後再試;

2.檢查防火牆軟體是否開放相應SocketTCP/udp埠;
  簡單的檢測方法是關閉防火牆軟體後再試;

3.如果伺服器端和客戶端均在本機上執行,則將相應的 serverIP="127.0.0.1",serveraddress="127.0.0.1";
伺服器端偵聽:
 listener = new TcpListener(IPAddress.Parse(serverIP), listenport);
               listener.Start();
客戶端與伺服器建立連線:
  clientsocket = new TcpClient(serveraddress, serverport);

4.如果伺服器執行在區域網或廣域網內,則將相應的
serverIP,serveraddress設為本機所在區域網或廣域網上的IP;

注意 serverport==listenport;

System.Net.Sockets.SocketException: 向一個無法連線的網路嘗試了一個套接字操作(System.Net.Sockets.SocketException:Network is unreachable)

IPAddress ipserver = IPAddress.Parse("192.x.x.x");

//IPAddress ipserver = IPAddress.Parse("127.0.0.1");這個沒問題

socket.Connect(ipserver, 4000);

------解決方案--------------------
"192.x.x.x" 不是一個有效的地址
127.0.0.1是回送地址,協議立即返回不進行任何網路傳輸
程式碼沒有任何問題,你需要檢查你所要連線的主機IP地址和埠號,用telnet ip port測試看看是不是能連上遠端主機


一、網上常用方法

1、當Socket.Conneted == false時,呼叫如下函式進行判斷

點選(此處)摺疊或開啟

  1. ///
  2. /// 當socket.connected為false時,進一步確定下當前連線狀態
  3. /// 
  4. /// 
  5. private bool IsSocketConnected()
  6. {
  7.     #region remarks
  8.     /********************************************************************************************
  9.      * 當Socket.Conneted為false時, 如果您需要確定連線的當前狀態,請進行非阻塞、零位元組的 Send 呼叫。
  10.      * 如果該呼叫成功返回或引發 WAEWOULDBLOCK 錯誤程式碼 (10035),則該套接字仍然處於連線狀態; 
  11.      * 否則,該套接字不再處於連線狀態。
  12.      * 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
  13.     ********************************************************************************************/
  14.     #endregion
  15.     #region 過程
  16.             // This is how you can determine whether a socket is still connected.
  17.             bool connectState = true;
  18.             bool blockingState = socket.Blocking;
  19.             try
  20.             {
  21.                 byte[] tmp = new byte[1];
  22.                 socket.Blocking = false;
  23.                 socket.Send(tmp, 0, 0);
  24.                 //Console.WriteLine("Connected!");
  25.                 connectState = true; //若Send錯誤會跳去執行catch體,而不會執行其try體裡其之後的程式碼
  26.             }
  27.             catch (SocketException e)
  28.             {
  29.                 // 10035 == WSAEWOULDBLOCK
  30.                 if (e.NativeErrorCode.Equals(10035))
  31.                 {
  32.                     //Console.WriteLine("Still Connected, but the Send would block");
  33.                     connectState = true;
  34.                 }
  35.                 else
  36.                 {
  37.                     //Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
  38.                     connectState = false;
  39.                 }
  40.             }
  41.             finally
  42.             {
  43.                 socket.Blocking = blockingState;
  44.             }
  45.             //Console.WriteLine("Connected: {0}", client.Connected);
  46.             return connectState;
  47.             #endregion
  48. }
2、根據socket.poll判斷

點選(此處)摺疊或開啟

  1. ///
  2. /// 另一種判斷connected的方法,但未檢測對端網線斷開或ungraceful的情況
  3. /// 
  4. /// 
  5. /// 
  6. static bool IsSocketConnected(Socket s)
  7. {
  8.     #region remarks
  9.             /* As zendar wrote, it is nice to use the Socket.Poll and Socket.Available, but you need to take into conside                ration 
  10.              * that the socket might not have been initialized in the first place. 
  11.              * This is the last (I believe) piece of information and it is supplied by the Socket.Connected property. 
  12.              * The revised version of the method would looks something like this: 
  13.              * from:http://stackoverflow.com/questions/2661764/how-to-check-if-a-socket-is-connected-disconnected-in-c */
  14.             #endregion
  15.     #region 過程
  16.             return !((s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0)) || !s.Connected);
  17.             /* The long, but simpler-to-understand version:
  18.                     bool part1 = s.Poll(1000, SelectMode.SelectRead);
  19.                     bool part2 = (s.Available == 0);
  20.                     if ((part1 && part2 ) || !s.Connected)
  21.                         return false;
  22.                     else
  23.                         return true;
  24.             */
  25.             #endregion
  26. }
總結:--1--此兩種方法出處可在函式體中的remark中找到連結
         --2--此兩種方法適用於對端正常關閉socket下的本地socket狀態檢測,在非正常關閉如斷電、拔網線的情況下不起作用
               因為Socket.Conneted存在bug,詳見.Net Bugs

二、支援物理斷線重連功能的類

        利用BeginReceive + KeepAlive實現物理斷線重連,初步測驗了一下,正常。(部分程式碼參考帖子#26blog在C#中利用keep-alive處理socket網路異常斷開)
        Keep-Alive機制的介紹請看TCP Keepalive HOWTO
        以此備忘,同時希望能幫助到有需要的同學。

點選(此處)摺疊或開啟

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Net.Sockets;
  6. using System.Net;
  7. using System.Threading;
  8. namespace MySocket
  9. {
  10.     public class Socket_wrapper
  11.     {
  12.         //委託
  13.         private delegate void delSocketDataArrival(byte[] data);
  14.         static delSocketDataArrival socketDataArrival = socketDataArrivalHandler;
  15.         private delegate void delSocketDisconnected();
  16.         static delSocketDisconnected socketDisconnected = socketDisconnectedHandler;
  17.         public static Socket theSocket = null;
  18.         private static string remoteHost = "192.168.1.71";
  19.         private static int remotePort = 6666;
  20.         private static String SockErrorStr = null;
  21.         private static ManualResetEvent TimeoutObject = new ManualResetEvent(false);
  22.         private static Boolean IsconnectSuccess = false; //非同步連線情況,由非同步連接回調函式置位
  23.         private static object lockObj_IsConnectSuccess = new object();
  24.         ///
  25.         /// 建構函式
  26.         /// 
  27.         /// 
  28.         /// 
  29.         public Socket_wrapper(string strIp, int iPort)
  30.         {
  31.             remoteHost = strIp;
  32.             remotePort = iPort;
  33.         }
  34.         ///
  35.         /// 設定心跳
  36.         /// 
  37.         private static void SetXinTiao()
  38.         {
  39.             //byte[] inValue = new byte[] { 1, 0, 0, 0, 0x20, 0x4e, 0, 0, 0xd0, 0x07, 0, 0 };// 首次探測時間20 秒, 間隔偵測時間2 秒
  40.             byte[] inValue = new byte[] { 1, 0, 0, 0, 0x88, 0x13, 0, 0, 0xd0, 0x07, 0, 0 };// 首次探測時間5 秒, 間隔偵測時間2 秒
  41.             theSocket.IOControl(IOControlCode.KeepAliveValues, inValue, null);
  42.         }
  43.         ///
  44.         /// 建立套接字+非同步連線函式
  45.         /// 
  46.         /// 
  47.         private static bool socket_create_connect()
  48.         {
  49.             IPAddress ipAddress = IPAddress.Parse(remoteHost);
  50.             IPEndPoint remoteEP = new IPEndPoint(ipAddress, remotePort);
  51.             theSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  52.             theSocket.SendTimeout = 1000;
  53.             SetXinTiao();//設定心跳引數
  54.             #region 非同步連線程式碼
  55.             TimeoutObject.Reset(); //復位timeout事件
  56.             try
  57.             {
  58.                 theSocket.BeginConnect(remoteEP, connectedCallback, theSocket);
  59.             }
  60.             catch (Exception err)
  61.             {
  62.                 SockErrorStr = err.ToString();
  63.                 return false;
  64.             }
  65.             if (TimeoutObject.WaitOne(10000, false))//直到timeout,或者TimeoutObject.set()
  66.             {
  67.                 if (IsconnectSuccess)
  68.                 {
  69.                     return true;
  70.                 }
  71.                 else
  72.                 {
  73.                     return false;
  74.                 }
  75.             }
  76.             else
  77.             {
  78.                 SockErrorStr = "Time Out";
  79.                 return false;
  80.             }
  81. 相關推薦

    C# + Socket 整理

    1.如果是採用TCP/udp協議進行連線,檢查windows防火牆是否開放相應SocketTCP/udp埠;   簡單的檢測方法是關閉windows防火牆後再試; 2.檢查防火牆軟體是否開放相應SocketTCP/udp埠;   簡單的檢測方法是關閉防火

    C# + Socket

    轉自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28765492&id=3793532 感謝作者的分享,收藏 一、網上常用方法 1、當Socket.Conneted == false時,

    C# 判斷Socket

    定時器裡面的事件 private void isConnendTimer_Tick(object sender, EventArgs e) { // 首先,Socket類的Connected屬性只表示最後一次I/

    teamtalk socket問題的查詢

    之前從teamtalk的核心庫裡面剝離出一個跨平臺網路庫,一開始用的好好的,可是在某些地方使用的時候總是出怪問題,有時候斷線重連就一直連不上,導致應用失聯,在實際使用場景中一直出問題,好不尷尬。 經過連三天的苦思冥想,除錯程式碼看輸出終於有些眉目了。 我是從以下幾個方面著手解決的,特此記錄一

    C# Mqtt

    在通過 MqttClient 客戶端連線之後,在服務端服務重啟時,客戶端如果沒有重連機制,則無法再接收到訂閱的訊息。 使用的 Mqtt 元件為:M2Mqtt.Net.dll 一些特性發現 (1)如果提供的服務端地址是不可解析的,會引發異常無法例項化 MqttClient 物件。 (2)Connect 無法

    Windows C語言 Socket程式設計 client端(客戶端)--

    瞭解了最基礎的C語言客戶端的編寫流程,稍稍加以改動即可實現斷線重連。 當伺服器掉線時,客戶端會以固定的頻率不停的重連。 #include <stdio.h> #include <winsock2.h> #pragma comme

    長連線 、短連線、心跳機制與(轉載) Socket的長連線和短連線

    概述 可承遇到,不知什麼原因,一個夜晚,機房中,大片的遠端呼叫連線斷開。 第二天早上,使用者訪問高峰,大部分伺服器都在獲取連線,造成大片網路阻塞。 服務崩潰,慘不忍睹的景象。 本文將從長連線和短連線的概念切入,再到長連線與短連線的區別,以及應用場景,引出心跳機制和斷線重連,給出程式碼實現。 從原

    Android Socket連線(模擬心跳包,,傳送資料等)

    這兩天做了一個專案是app通過socket連線自動炒菜機,給炒菜機發指令,炒菜機接收到指令會執行相應的操作。(程式雖然做的差不多了,然而我連炒菜機長什麼樣都沒見過) 其實作為一個會做飯的程式猿,我堅信還是自己動手做的飯菜比較好吃,畢竟做飯還是很有趣的。 閒話不

    C#實現adsl方法總結

    using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Runtime.InteropServices; using System.Window

    Windows寬頻C#)

    問題 最近電腦寬頻總是自動掉線,蛋疼啊。 在網路上下載了工具,實現自動重連,但是都帶廣告著啊,不能忍 不能忍。 思路 用C#操作寬頻連線,包括Java或者其他語言操作寬頻連線,一個很簡單的方法

    nodejs中mysql

    調試 狀態 pan var 參考 ble prot nec clas 之前寫了個小程序Node News,用到了MySQL數據庫,在本地測試均沒神馬問題。放上服務器運行一段時間後,偶然發現打開頁面的時候頁面一直處於等待狀態,直到Nginx返回超時錯誤。於是上服務器檢查了遍,

    android 實現mqtt訊息推送,以及不停的問題解決

    前段時間專案用到mqtt的訊息推送,整理一下程式碼,程式碼的原型是網上找的,具體哪個地址已經忘記了。 程式碼的實現是新建了一個MyMqttService,全部功能都在裡面實現,包括連伺服器,斷線重連,訂閱訊息,處理訊息,釋出訊息等基本操作。 首先新增依賴: dependencies { &

    django的資料庫

    django每次查詢都會被把連線關閉,想保持長連線方法如下: from django.core import signals from django.db import close_connection # 取消訊號關聯,實現資料庫長連線 signals.request

    【UE4】 第12講 FSocket

    (版權宣告,禁止轉載) 【第03講】 實現了FSocket的連網基礎功能,這一講實現一下 斷線重連 <如果資深前輩發現有理解錯誤,還請不吝指正> <1> 建立Socket,設定阻塞模式(預設創建出來的就是阻塞模式,不用設定)  

    ActiveMQ的機制

    primary active 節點 語法 無限 機制 新的 bubuko 獲取 斷線重連機制是ActiveMQ的高可用性具體體現之一。ActiveMQ提供failover機制去實現斷線重連的高可用性,可以使得連接斷開之後,不斷的重試連接到一個或多個brokerURL。 默認

    關於資料庫的一點點思考

    最近在寫資料庫連結池,一個不可逃避的問題就是資料庫斷線重連。 查了很多資料,因為公司有很多專案用了 TP5 於是也去看了它的原始碼。 tp5的實現其實很簡單,配置了一些資料庫連線相關的錯誤資訊關鍵詞(句),然後在執行語句時 catch 異常資訊進行比對: // 伺服器斷線標識字元 p

    Yii2實現mysql[轉載]

    最近遇到“Yii2實現mysql斷線重連”問題,找了好久資料,最後找到這篇文件是說明了該情況的,感謝這位作者的分享,記錄下來,必備以後查閱。 原文連結:https://www.yiichina.com/topic/7296 Yii2實現資料庫斷線重連 一、前話 在工作中,有時候一

    netty4.0 心跳檢測與操作

    因為最近專案最近要用netty,服務端放在雲端,客戶端發在內網。那如何實現netty長連線和斷線重連呢(網路故障或者其他原因,客戶端要無限取重連服務端)。接下來我們看一下如何實現這個兩個功能呢。 服務端程式碼如下: package com.example.nettydem

    mqtt協議 springboot2.0.4 mqttv3 釋出訂閱程式碼呼叫,mqtt

    mqttv3 釋出訂閱程式碼呼叫 我用的是springboot2.0.4 直接上程式碼: pom.xml <dependency> <groupId>org.eclipse.paho</groupId>

    iOS MQTT使用案例 ()

    iOS MQTT使用案例 (斷線重連) 參考了 iOS MQTT—-MQTTClient實戰-看這篇的就夠了 大神寫的這篇 git: MQTT-Client-Framework 介紹啥的看百度,上面大神寫的就行了,直接上乾貨。 安裝: pod 'MQTTClient'