<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      用代碼控制網絡斷開與重連

      看到這個標題,如果你想說誰會這么蛋疼,有網不好好上,那么說明你還是一個純潔的少年。自動重撥的需求所在多有,主要是為了繞過各大網站對相同IP地址的重復請求次數限制等等。具體的我不說了,說多了說我教壞小孩子。我最近研究這個只是因為我想寫個軟件自動播放和下載某個網站的視頻,but這個網站一天只讓同個IP免費看五個視頻,我又摳不愿意花錢,但是又特別想多看多載幾部。什么,你要我把網站地址告訴你?還是算了吧,傳播XX(se)OO(qing)是違法的知道不。

      按慣例,先聲明:技術知識浩瀚無垠,筆者但求淺嘗輒止便心滿意足,所以,本文并不確保描述的準確性,若有錯誤和不足之處請不吝賜教。

      上網方式簡介


      趁此機會簡單了解下各類網絡接入方式。以下描述主要來自淺談各種寬帶上網的方法

      撥號上網:20世紀90年代剛有互聯網的時候,老百姓上網使用最為普便的一種方式是撥號上網。只要用戶擁有一臺個人電腦、一個外置或內置的調制解調器(Modem)和一根電話線,再向本地ISP供應商申請自己的賬號,或購買上網卡,擁有自己的用戶名和密碼后,然后通過撥打ISP的接入號連接到Internet上。那個時候,出差的人們常常會問賓館能否撥號上網,然后問撥什么號,之后以緩慢的速度發送郵件或“暢游”網絡。撥號方式理論上的最高速率56KBIT/S。除了速度慢外,同時只能進行一項工作,比如上網了電話就打不進來。

      ISDN:準確地說應是N-ISDN,即窄帶ISDN,它主要提供64kbit/s到2Mbit/s的接入能力、目前推向用戶的ISDN業務是基本速率接口,即2B+D,每個B通道為64kbit/s,D通道為16kbit/s,ISDN在Internet接入方面比普通用戶以56kbit/s的Modem上網具有無可比擬的優勢。首先,由于ISDN提供了2B+D的功能,使得用戶可以一面以64kbit/s的速度上網,一面又可以同時使用另一通道打電話而互不干擾,非常方便;其次,ISDN是數字式設備,因而接入速度相當快,不像Modem那樣要有很長的建立時間,全數字的網絡使建立只需幾秒鐘;最后,由于ISDN提供2B+D方式,使得用戶可以綁定兩個B通道上網,最高速率可達128kbit/s,比56k Modem的接入速率快2.2倍,真正可以做到網上沖浪。

      ADSL:近幾年最普遍的網絡接入方式。長期以來通信用戶的電話機經過"對絞銅線"的用戶線連至市內交換局,進入公共交換的通信網(PSTN),接至對方用戶的電話機,使雙方得以互相會話。對絞銅線為傳統的模擬電話提供300~3400Hz 的頻帶,為了適應電話用戶使用低速數據通信,曾加裝調制一解調器(modem),使速率33kb/s 和最高56kb/s 的數據信號能夠通過模擬話音頻帶與對方實行數據通信。這就是撥號上網方式的基礎。話音modem 只能提供56kb/s 的數據速率。為什么對絞銅線只能傳輸以56kb/s 為限度的數據呢?應該說,這不是對絞銅線傳輸能力的限度,而是通信網中的交換機有限制,它對電話通信只是分配一個話音頻帶。雖然用戶的數據信息經過話音modem,交換機并不認出它是話音modem 傳來的數據信號,而只是對它當作話音信號看待。對絞銅線本身并不限制定帶數據信號的傳輸,只要避開窄帶交換機,用戶就可以把寬帶數據信號送進通信網。因此我們說,用戶線如避開了窄帶的話音交換機,就可成為"數字用戶線"(DSL,Digital Subscriber Line)。簡單地說,ADSL可以利用現有的電話線網絡,只要在線路兩端加裝ADSL設備,即可為用戶提供高寬帶服務,提供8MBIT/S的高速下行速率,遠高于ISDN速率,而上行速率有1MBIT/S,是普通電話拔號MODEM的百倍以上,傳輸距離能達3-5KM。當然ADSL的商業化推進也經過了各方面多年的努力。有人會問,“我家用的就是ADSL,怎么每次還要彈出一個撥號界面讓我輸入賬號密碼呢?”實際上,ADSL本身是不需要撥號的,而是一種專線鏈接。撥號的目的僅僅是認證用戶的身份并進行計費,因此叫做虛擬撥號。虛擬撥號需要用到虛擬撥號軟件,常用的有WinPoET ,虛擬撥號軟件在安裝過程中會提示將撥號綁定到與ADSL Modem 相連的網卡。配置好以后,撥號形式與56Kbps模擬Modem完全一樣,在對話框里輸入ISP提供的用戶名和密碼就可以了。ADSL還涉及到PPPOE的概念,有空再研究吧。

      光纖入戶:很明顯,最直觀的區別就是傳輸介質不同,當然相關的接入技術肯定也是不同的,網速比ADSL又有了很大提升,就不贅述了。筆者安裝光纖時,電信也給了一個類似Modem的東西,工作人員也把它叫做“貓”,其實和撥號方式用的Modem不是同個東西,但是本質還是主要用來處理信號轉換。

      ISDN沒接觸過就不說了,傳統撥號和ADSL都可以通過調用撥號程序控制網絡的斷開與連接,如果ADSL入戶時接入到路由器上,那么可以通過重啟路由器的方式進行IP更換。光纖入戶時常也接路由器(光貓原本自帶無線路由功能,但是有時電信會把這個功能給鎖掉讓你用不了,很坑爹),但是賬號和密碼是保存在光貓里的,所以要重啟的是光貓(似乎也有方法可以通過路由器進行撥號,筆者沒研究過)。重啟路由器和光貓很簡單,調用設備管理頁面的重啟請求即可。下面我們主要講如何通過自動撥號進行網絡重連。

      RAS概述


      現如今,社會已經離不了網絡,企事業單位對網絡的需求也在不斷擴大,各地分支機構都需要與總部隨時進行信息交換。雖然通過Intemet能很好實現遠程數據的傳輸,但需要總部與各地分支機構都擁有良好的上網條件和IP地址。在實際工作中,出于成本上的考慮,大多數中小型企業多采用傳統的通過調制解調器和電話線直接撥號的方式來實現遠程數據的傳輸(并不一定經由Internet,更類似于局域網)。

      遠程訪問服務(Remote Access seryice)利用公共交換電話網絡(PSTN)把遠離局域網(LAN)的計算機連接到局域網上來,遠程計算機(RAS客戶機)可以獲得LAN用戶的所有服務和權限,并訪問、共享該LAN上的資源。它所實施的網絡互聯架構,在提供網絡互聯的同時,可以集中發布各種應用程序,包括Web應用程序,以及幾乎所有部署在臺式機的應用程序。分析結果顯示,維持RAS正常使用所需要的帶寬相當低,用戶端提供最低28Kbps快速訪問。相對于傳統的組網方案, RAS提供了更為快速、安全、靈活和可管理的遠程應用接入方案,使人們可以隨需應變,通過任何網絡連接方式對企業進行隨時隨地的安全訪問,為企業的 ERP 、 CRM 、 OA 等信息應用系統全面提速。RAS適用于行業用戶使用,如:企業辦公網絡,政府辦公網絡、稅收征收系統、電力系統、醫療領域等等。

      遠程訪問服務支持撥號網絡(DUN)連接與虛擬專用網絡(VPN)連接兩種不同的遠程訪問連接方式。撥號網絡(DUN)連接就是遠程客戶機利用一個連接了電話線的調制解調器,通過撥號的方式呼叫遠程計算機并建立連接。虛擬專用網絡(VPN)是遠程客戶機使用基于TCP/IP協議的專門隧道協議(如PPTP、L2TP),通過虛擬專用網絡服務器的虛擬端口,借助其他網絡(如Intemet),實現一種邏輯上的直接連接。

      VPN屬于遠程訪問技術,簡單地說就是利用公用網絡架設專用網絡。例如某公司員工出差到外地,他想訪問企業內網的服務器資源,這種訪問就屬于遠程訪問。在傳統的企業網絡配置中,要進行遠程訪問,傳統的方法是租用DDN(數字數據網)專線或幀中繼,這樣的通訊方案必然導致高昂的網絡通訊和維護費用。對于移動用戶(移動辦公人員)與遠端個人用戶而言,一般會通過撥號線路(Internet)進入企業的局域網,但這樣必然帶來安全上的隱患。

      讓外地員工訪問到內網資源,利用VPN的解決方法就是在內網中架設一臺VPN服務器。外地員工在當地連上互聯網后,通過互聯網連接VPN服務器,然后通過VPN服務器進入企業內網。為了保證數據安全,VPN服務器和客戶機之間的通訊數據都進行了加密處理。有了數據加密,就可以認為數據是在一條專用的數據鏈路上進行安全傳輸,就如同專門架設了一個專用網絡一樣,但實際上VPN使用的是互聯網上的公用鏈路,因此VPN稱為虛擬專用網絡,其實質上就是利用加密技術在公網上封裝出一個數據通訊隧道。有了VPN技術,用戶無論是在外地出差還是在家中辦公,只要能上互聯網就能利用VPN訪問內網資源,這就是VPN在企業中應用得如此廣泛的原因。

      P/Invoke


      我們可以借助RASapi實現軟件的自動撥號。RAS APl最早是在windows for workgroup 3.11中出現的,現已成為win32 API的一個組成部分。RAS API提供了專門用于實現RAS功能的函數,根據其具體的功能分別存放在API32.DLL、RASDLG.DLL和RASSAPI.DLL三個動態鏈接庫中。其中,RASAPl32.DLL封裝了RAS客戶功能的函數,RASDLG.DLL封裝了幾個基于對話框的功能函數,RASSAPI.DLL則封裝了RAS Server的一些管理函數。 

      RAS API將整個撥號網絡視為RAS電話簿(Phonebook),而每一個連接視為電話簿條目(PhonebookEntry)。調用RasCreatePhonebookEntry創建新的連接,調用RasDial進行撥號,調用RasEnumEntries獲得當前系統已有的所有連接,調用其它的RAS函數還可以分別實現獲取或設置連接參數等功能。 

      作為.NETer,偶爾要借助P/Invoke調用Win32Api,以RASAPI中的核心函數RasDial為例,看用C#如何封裝對該函數的調用。

      還有個api名曰InternetDial,也能用來寫撥號程序,就不知道它和RasApi的區別有哪些。MSDN里說道InternetDial does not support double-dial connections, SmartCard authentication, or connections that require registry-based certification. Starting on Windows Vista and Windows Server 2008, the WinINet dial-up functions use the RAS functions to establish a dial-up connection. WinINet supports the functionality documented in the RasDialDlg function. 所以我想現在還是用RAS比較靠譜一點。

      首先在MSDN中查看RasDial的定義如下:

      DWORD RasDial(
        _In_   LPRASDIALEXTENSIONS lpRasDialExtensions,
        _In_   LPCTSTR lpszPhonebook,
        _In_   LPRASDIALPARAMS lpRasDialParams,
        _In_   DWORD dwNotifierType,
        _In_   LPVOID lpvNotifier,
        _Out_  LPHRASCONN lphRasConn
      );

      然后我們要將Win32類型轉為C#類型。由于 DWORD 是 4 字節的整數,因此我們可以使用 int 或 uint 作為 C# 對應類型。由于 int 是 CLS 兼容類型(可以用于所有 .NET 語言),以此比 uint 更常用,并且在多數情況下,它們之間的區別并不重要。以P或LP開頭的類型一般都是指針,對應的C#類型需要為引用類型,如果作為參數使用,那么也可以使用值類型,前面加上ref/out關鍵字即可;還有一種方法,就是使用CLR中的System.IntPrt作為萬能指針去對應任意Win32指針類型,它沒有要求一開始就定義對應的數據類型,后面用到時再賦予即可(概念上有點類似于Object)。不像系統中的其他基類型,IntPtr 并沒有固定的大小。相反,它在運行時的大小是依底層操作系統的正常指針大小而定的。這意味著在 32 位的 Windows 中,IntPtr 變量的寬度是 32 位的,而在 64 位的 Windows 中,實時編譯器編譯的代碼會將 IntPtr 值看作 64 位的值。當在托管代碼和非托管代碼之間封送不透明指針時,這種自動調節大小的特點十分有用。

      我們平時常說的32位、64位系統,這里的位數其實指的是最大尋址空間,即內存的最大大小,也就是說使用32位操作系統支持的內存也最多為2的32次方,就是4G。和數據類型占用的字節大小沒有關系。

      RASDIALEXTENSIONS是指向一個結構的指針,定義如下:

      typedef struct _RADIALEXTENSIONS {
        DWORD              dwSize;
        DWORD              dwfOptions;
        HWND               hwndParent;
        ULONG_PTR          reserved;
        ULONG_PTR          reserved1;
        RASEAPINFO         RasEapInfo;
        BOOL               fSkipPppAuth;
        RASDEVSPECIFICINFO RasDevSpecificInfo;
      } RASDIALEXTENSIONS, *PRASDIALEXTENSIONS;

      根據上述,在c#中我們可以使用class替代它,由于這個結構是作為RasDial函數的一個參數傳遞,因此我們也可以使用struct替代,并在調用方法的時候在此參數前加上ref/out(若將參數作為一個整體操作,那么class也必須加上ref/out,避免出現實參/形參引用不一致的情況),當然,在方法調用的時候,我們也可以使用System.IntPrt指向之,略微麻煩一點的是,IntPrt需要手動為其分配非托管內存并寫入數據,所幸借助System.Runtime.InteropServices.Marshal類的相關方法,這部分工作也很簡單。

      c#表示如下(RASDIALEXTENSIONS最后兩個字段是Win7之后新增的,在編碼的時候要注意):

              [StructLayout(LayoutKind.Sequential, Pack = 4)]
              public struct RASDIALEXTENSIONS
              {
                  public int size;
                  public RDEOPT options;
                  public IntPtr handle;
                  public IntPtr reserved;
                  public IntPtr reserved1;
                  public RASEAPINFO eapInfo;
      #if (WIN7 || WIN8)
                  public bool skipPppAuth;
                  public RASDEVSPECIFICINFO devSpecificInfo;
      #endif
              }

      WIN7、WIN8是在VS里自定義的條件編譯符號,略過不談。StructLayout特性指示結構字段在內存中如何分布,當導出到非托管代碼時非托管對象亦按此布局。StructLayout有四個屬性:

      1. LayoutKind,有三個枚舉值:Sequential,對象的成員按照它們出現的順序依次布局,并且同StructLayout的另一個屬性Pack有關,詳細規則可以參看內存對齊的規則以及作用,那篇文章中的#pragma pack()同這里的Pack作用一樣;Explicit,對象的各個成員的精確位置被顯式控制,每個成員必須使用 System.Runtime.InteropServices.FieldOffsetAttribute指示該字段在類型中的位置,當映射到C/C++的union時,該枚舉值非常有用;Auto,運行時自動對象的成員選擇適當的布局,可能會對字段順序進行調整,使實例占用盡可能少的內存(當然前提是各個字段獨享自己的內存,不同于union)。考慮到CPU讀取效率,一般采用LayoutKind.Sequential。
      2. Pack,第1條已述。
      3. CharSet,指示字符是單字節or雙字節,這主要是歷史遺留問題。可以將之設為Auto,這樣,在 Windows NT、Windows 2000、Windows XP 和 Windows Server2003 系列上,默認值為 System.Runtime.InteropServices.CharSet.Unicode;在 Windows 98 和 Windows Me 上,默認值為 System.Runtime.InteropServices.CharSet.Ansi。
      4. Size,指示類或結構的絕對大小。不常用,但是如果需要在結構末尾分配額外的空間,則可能會用到此屬性。 

      結構體的ULONG_PTR等表示基元類型指針的字段,只能使用IntPtr映射;若字段有預定義的若干值表示有意義的狀態指示等,則可以使用enum映射,如dwfOptions標記RasDial的某些擴展信息,這些標記可以用枚舉值表示。

              [Flags]
              public enum RDEOPT
              {
                  None = 0x0,
                  UsePrefixSuffix = 0x1,
                  PausedStates = 0x2,
                  IgnoreModemSpeaker = 0x4,
                  //...
              }

      RasDial還有個參數值得注意——lpvNotifier——雖然LPVOID類型表示這是個不透明指針,用IntPtr即可,但文檔所述表明這是個回調函數參數,當 Win32 函數需要返回多項數據時,通常都是通過回調機制來實現的,開發人員將函數指針傳遞給函數。.Net中有個類型專門作為方法的引用——Delegate,所以用Delegate映射更精確更方便。

      最終RasDial函數的C#封裝版本如下:

              [DllImport(NativeMethods.RasApi32Dll, CharSet = CharSet.Unicode)]
              private static extern int RasDial(
                  IntPtr lpRasDialExtensions,
                  string lpszPhonebook,
                  IntPtr lpRasDialParams,
                  RasNotifierType dwNotifierType,
                  Delegate lpvNotifier,
                  out RasHandle lphRasConn);

      可以看到lpRasDialExtensions使用的類型是IntPtr,如前所述,我們要手動為其分配內存(非托管),并寫入相應數據,關鍵代碼如下:

       1             try
       2             {
       3                 IntPtr lpRasDialExtensions = IntPtr.Zero;
       4                 var extensions = new RASDIALEXTENSIONS();
       5                 //根據StructLayout相關屬性計算內存大小
       6                 int extensionsSize = Marshal.SizeOf(typeof(RASDIALEXTENSIONS));
       7                 extensions.size = extensionsSize;
       8 #if (WIN7 || WIN8)
       9                 extensions.devSpecificInfo.size = Marshal.SizeOf(typeof(RASDEVSPECIFICINFO));
      10 #endif
      11                 lpRasDialExtensions = Marshal.AllocHGlobal(extensionsSize);
      12                 Marshal.StructureToPtr(extensions, lpRasDialExtensions, true);
      13             }
      14             catch (Exception)
      15             {
      16                 //...
      17             }
      18             finally
      19             {
      20                 if (lpRasDialExtensions != IntPtr.Zero)
      21                 {
      22                     Marshal.FreeHGlobal(lpRasDialExtensions);
      23                 }
      24             }

      代碼并不復雜,其中Marshal.StructureToPtr(object structure, IntPtr ptr, bool fDeleteOld)方法的第三個參數說明如下:

      假設 ptr 指向非托管內存塊。此內存塊的布局由相應的托管類 structure 描述。StructureToPtr將字段值從結構封送到指針。假設 ptr 塊包含引用字段,該字段指向當前包含“abc”的字符串緩沖區。假設托管端上相應的字段是包含“vwxyz”的字符串。如果不另行通知它,StructureToPtr將分配一個新的非托管緩沖區來保存“vwxyz”,并將它掛鉤到ptr 塊。這將丟棄舊緩沖區“abc”使之漂移而不將其釋放回非托管堆。最后,您將得到一個孤立的緩沖區,它表示在代碼中存在內存泄漏。如果將 fDeleteOld 參數設置為真,則StructureToPtr 在繼續為“vwxyz”分配新緩沖區之前釋放保存“abc”的緩沖區。

      調用結束后記住要使用Marshal.FreeHGlobal釋放非托管內存。

      DotRas


      以上代碼來自于一個開源項目DotRas,雖然我并不提倡重復造輪子,但大概知道輪子怎么造總沒有壞處。由于筆者家里條件不允許——光纖入戶——so,我借用朋友的虛擬機(ADSL)進行DotRas的調用測試,主要代碼如下:

       1 //斷開
       2 private void btnHangUp_Click(object sender, RoutedEventArgs e)
       3 {
       4     if (_dataContext.SelectedRasConnection != null)
       5     {
       6         var conns = RasConnection.GetActiveConnections();//獲取當前所有活動連接
       7         var conn = conns.First(o => o.EntryId == _dataContext.SelectedRasConnection.EntryId);
       8         if (conn != null)
       9         {
      10             RasIPInfo ipAddresses = (RasIPInfo)conn.GetProjectionInfo(RasProjectionType.IP);
      11             tbTestInfo.Text += "_前_" + ipAddresses.IPAddress.ToString();
      12             conn.HangUp();//斷開,斷開后RasConnection.GetActiveConnections()返回值里就沒它了
      13             System.Threading.Thread.Sleep(10000);
      14             DialUp(_dataContext.SelectedRasConnection.EntryName);
      15         }
      16     }
      17 }
      18 
      19 //撥號連接
      20 private void DialUp(string entryname)
      21 {
      22     RasDialer dialer = new RasDialer();
      23     dialer.EntryName = entryname;
      24     dialer.PhoneNumber = " ";
      25     dialer.AllowUseStoredCredentials = true;
      26     dialer.PhoneBookPath = RasPhoneBook.GetPhoneBookPath(RasPhoneBookType.AllUsers);
      27     dialer.Timeout = 1000;
      28     dialer.Dial();
      29 
      30     if (_dataContext.SelectedRasConnection != null)
      31     {
      32         var conns = RasConnection.GetActiveConnections();
      33         var conn = conns.First(o => o.EntryId == _dataContext.SelectedRasConnection.EntryId);
      34         if (conn != null)
      35         {
      36             RasIPInfo ipAddresses = (RasIPInfo)conn.GetProjectionInfo(RasProjectionType.IP);
      37             tbTestInfo.Text += "_后_" + ipAddresses.IPAddress.ToString();
      38         }
      39     }
      40 }

      界面如圖:

      點斷開后,果然遠程桌面斷開了:

      10秒鐘后,虛擬機重撥連接,再等待一段時間后(這個時間比較長有1到3分鐘,遠遠沒達到實用的標準,可能是花生殼域名重新解析的緣故;經朋友在本地測試,速度杠杠的),界面重新展現:

      可以看到前后的IP是不一樣的。

       

      其它參考資料:

      基于VC++的RAS撥號連接技術及其應用((武漢科技大學)何璐、陳和平、肖剛)

      VPN——虛擬專用網絡

      C#中使用Win32類庫

      Calling Win32 DLLs in C# with P/Invoke

      C# 托管內存與非托管內存之間的轉換(結合Unity3d的實際開發)

       

      轉載請注明本文出處:http://www.rzrgm.cn/newton/p/4299352.html

      posted @ 2015-03-09 09:34  萊布尼茨  閱讀(10939)  評論(23)    收藏  舉報
      主站蜘蛛池模板: 一区二区中文字幕久久| 人妻夜夜爽天天爽| 亚洲精品一区二区三区片| 国内精品久久黄色三级乱| 日本中文字幕有码在线视频| 亚洲色大成网站www永久一区 | 少妇高潮激情一区二区三| 中文人妻av高清一区二区| 性久久久久久| 老司机性色福利精品视频| 少妇伦子伦精品无吗| 久久久一本精品99久久精品88| 免费大片av手机看片高清 | 国产一区二区在线有码| 18禁黄网站免费| 国产一区二区黄色激情片| 色一伦一情一区二区三区| 久久综合亚洲鲁鲁九月天| 国产成人啪精品午夜网站| 一二三四中文字幕日韩乱码| 国产女人高潮视频在线观看| 久女女热精品视频在线观看| 精品熟女日韩中文十区| 久久精品第九区免费观看| 亚洲2017天堂色无码| 国产亚洲999精品aa片在线爽| 国产一区二区三区在线观看免费| 亚洲国产成人av毛片大全| 国产精品内射在线免费看| 国产精品成人一区二区三区| 大尺度国产一区二区视频| 国产精品亚洲二区在线播放 | 国产精品色哟哟在线观看| 国精品91人妻无码一区二区三区| 国产SM重味一区二区三区| 日韩av一区二区三区在线| 成人免费无遮挡无码黄漫视频| 中文字幕日韩有码av| 亚洲码国产精品高潮在线| 欧美午夜成人片在线观看| 国产亚洲精品AA片在线爽|