如何在C#程序中通过modem拨号上网,并且随时能够判断是否已联网?

主  题:  如何在C#程序中通过modem拨号上网,并且随时能够判断是否已联网?
作  者:  aleckz ()  
等  级:
信 誉 值:  100
所属论坛:  .NET技术 C#
问题点数:  100
回复次数:  12
发表时间:  2003-4-27 14:59:22

如何在C#程序中通过modem拨号上网,并且随时能够判断是否已联网?

用API实现,还是调用外部的拨号网络程序?
最好能用前者实现.

如何在程序中得到当前是否已上网的状态呢?
操作完成后如何关闭网络连接?

小弟正在做一个专用软件,目标运行平台是win98,
我的开发平台是WinXP上的VS.NET 2002.

请大家帮忙!!谢谢!!!!



回复人: snewxf(心疤) ( 一星(中级)) 信誉:110 2003-4-27 15:06:58 得分:0

http://expert.csdn.net/Expert/topic/948/948369.xml?temp=.4689752
其实你搜一下以前的贴子。就能解决你的问题了。呵呵!好运!

回复人: snewxf(心疤) ( 一星(中级)) 信誉:110 2003-4-27 15:07:57 得分:0

最难搞的是ADSL呀!555555555到现在我还没搞定:(2000下搞定了。XP下没搞定。我不知道2003版下肯定也搞不定了:(

回复人: aleckz() ( 一级(初级)) 信誉:100 2003-4-27 16:53:23 得分:0

我看了那个帖子,只提到如何检测上网状态,没有具体如何联网和断开的代码阿?
我对windows api确实不太熟。请哪位给个具体的例子吧!谢谢!!!

回复人: snewxf(心疤) ( 一星(中级)) 信誉:110 2003-4-27 21:23:18 得分:0

引用名字空间;
using System.Runtime.InteropServices;
,,,,,,,,,,,,,,,,,,,
先定义:

[DllImport("wininet.dll")]
public static extern bool InternetGetConnectedState(
    [In, Out, MarshalAs(UnmanagedType.U4)] ref int lpdwFlags, int dwReserved);

bool isConnect =InternetGetConnectedState(ref flag,0);
if(isConnect == true)
{
//你以连接internet;
}
else
{
//你没有连接internet;
}

回复人: snewxf(心疤) ( 一星(中级)) 信誉:110 2003-4-27 21:25:21 得分:0

api请参看:
ms-help://MS.VSCC/MS.MSDNVS.2052/WinInet/workshop/networking/wininet/reference/functions/InternetGetConnectedState.htm

回复人: aleckz() ( 一级(初级)) 信誉:100 2003-4-28 14:00:27 得分:0

在.NET中用起来比较麻烦……

[DllImport("wininet.dll")]
public static extern bool InternetAutoDial(
    MarshalAs(UnmanagedType.U4) int dwFlags,
    IntPtr hwndParent);

这个函数的第二个参数,SDK文档说是当前windows的handler.
我的C#程序里面如何调用啊?

回复人: aleckz() ( 一级(初级)) 信誉:100 2003-4-29 0:13:28 得分:0

snewxf(心疤)大哥:帮帮我啊!

回复人: snewxf(心疤) ( 一星(中级)) 信誉:110 2003-4-29 1:03:28 得分:0

http://www.ccidnet.com/tech/guide/2001/08/20/58_3014.html
设为0

回复人: snewxf(心疤) ( 一星(中级)) 信誉:110 2003-4-29 1:07:05 得分:100

设为:IntPtr.Zero
应该也可以设为:this.Handle
好运!

回复人: loke(细东) ( 一级(初级)) 信誉:100 2003-09-29 14:58:00 得分:0

我在windows 2000 AD上成功了代码如下:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
namespace Ras
{
    //尊重知识产权,原类名空间名未作更改
    public class RasManager
    {
        //拨号数据
        public const int RAS_MaxEntryName = 256;
        public const int RAS_MaxPhoneNumber = 128;
        public const int UNLEN = 256;
        public const int PWLEN = 256;
        public const int DNLEN = 15;
        public const int MAX_PATH = 261;
        public const int RAS_MaxDeviceType = 16;
        public const int RAS_MaxDeviceName = 128;
        public const int RAS_MaxCallbackNumber = RAS_MaxPhoneNumber;
        //回调函数
        public delegate void Callback(uint unMsg, int rasconnstate, int dwError);
        //断线事件数据
        private bool Keep;
        public System.Threading.Thread KeepRas;
        public event RasDeconnect rasDecoonect;
        public delegate void RasDeconnect(object render, Ras.RasDecoonectAgrs e);

        //拨号结构
        [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)]
        public struct RASDIALPARAMS
        {
            public int dwSize;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxEntryName + 1)]
            public string szEntryName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxPhoneNumber + 1)]
            public string szPhoneNumber;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxCallbackNumber + 1)]
            public string szCallbackNumber;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = UNLEN + 1)]
            public string szUserName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = PWLEN + 1)]
            public string szPassword;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DNLEN + 1)]
            public string szDomain;
            //win98下面,以下的两个变量去掉,否则产生610错误
            public int dwSubEntry;
            public int dwCallbackId;
        }

        //拨号函数
        [DllImport("Rasapi32.dll", CharSet = CharSet.Auto)]
        public static extern int RasDial(int lpRasDialExtensions, string lpszPhonebook, ref RASDIALPARAMS lprasdialparams, int dwNotifierType, Callback lpvNotifier, ref int lphRasConn);
        private RASDIALPARAMS RasDialParams;
        //拨号连接句柄
        private int Connection;
        //断开拨号
        [DllImport("Rasapi32.dll", CharSet = CharSet.Auto)]
        public static extern int RasHangUp(long lphRasConn);
        //获取当前拨号的数据
        [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)]
        public struct RASCONN
        {
            public int dwSize;
            public int hrasconn;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxEntryName + 1)]
            public string szEntryName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxDeviceType + 1)]
            public string szDeviceType;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxDeviceName + 1)]
            public string szDeviceName;
        }

        //获取当前拨号
        [DllImport("Rasapi32.dll", CharSet = CharSet.Auto)]
        public static extern int RasEnumConnections(ref RASCONN lprasconn, ref int lpcb, ref int lpcConnections);

        //构造函数
        public RasManager()
        {
            Connection = 0;
            RasDialParams = new RASDIALPARAMS();
            RasDialParams.dwSize = Marshal.SizeOf(RasDialParams);
        }

        //属性区域
        #region Properties
        //注册姓名
        public string UserName
        {
            get { return RasDialParams.szUserName; }
            set { RasDialParams.szUserName = value; }
        }
        //注册密码
        public string Password
        {
            get { return RasDialParams.szPassword; }
            set { RasDialParams.szPassword = value; }
        }
        //拨号名
        public string EntryName
        {
            get { return RasDialParams.szEntryName; }
            set { RasDialParams.szEntryName = value; }
        }
        //拨号电话
        public string PhoneNumber
        {
            get { return RasDialParams.szPhoneNumber; }
            set { RasDialParams.szPhoneNumber = value; }
        }
        #endregion

        //获取当前拨号,如果拨号唯一,返回1,并且赋值句柄,拨号不为一,返回拨号个数,出错则返回错误码
        public int GetConnect()
        {
            RASCONN lpRasConn = new RASCONN();
            int lpcb = 0;
            int lpcConnections = 0;
            lpRasConn.dwSize = Marshal.SizeOf(lpRasConn);
            lpcb = lpRasConn.dwSize;
            int nRet = RasEnumConnections(ref lpRasConn, ref lpcb, ref lpcConnections);
            if (nRet == 0)
                if (lpcConnections == 1)
                {
                    Connection = lpRasConn.hrasconn;
                    return lpcConnections;
                }
                else
                    return lpcConnections;
            else
                return nRet;
        }

        //同步拨号
        public bool Connect()
        {
            Connection = 0;
            //根据win自己的说明,要执行已有的拨号
            //RasDialParams.szEntryName = 你的拨号连接的名字,并且保持RasDialParams.szPhoneNumber = "";
            //如果要直接拨号
            //RasDialParams.szEntryName = "";RasDialParams.szPhoneNumber = 电话号码。
            //但是我没法检测,有小猫的朋友可以试试
            RasDialParams.szEntryName += "\0";
            RasDialParams.szPhoneNumber += "\0";
            RasDialParams.szUserName += "\0";
            RasDialParams.szPassword += "\0";
            int result = RasDial(0, null, ref RasDialParams, 0, null, ref Connection);
            if (result == 0)
            {
                //拨号成功开始跟踪拨号情况
                if (!Keep)
                {
                    Keep = true;
                    KeepRas = new System.Threading.Thread(new System.Threading.ThreadStart(this.CheckRasEvent));
                    KeepRas.Start();
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        public int AConnect()
        {
            Callback rasDialFunc = new Callback(RasManager.RasDialFunc);
            RasDialParams.szEntryName += "\0";
            RasDialParams.szPhoneNumber += "\0";
            RasDialParams.szUserName += "\0";
            RasDialParams.szPassword += "\0";
            int result = RasDial(0, null, ref RasDialParams, 0, rasDialFunc, ref Connection);
            return result;
        }

        //断开拨号
        public int DeConnect()
        {
            int result = RasHangUp(Connection);
            Connection = 0;
            Keep = false;
            System.Threading.Thread.Sleep(3000);
            return result;
        }

        //异步拨号的回调函数
        public static void RasDialFunc(uint unMsg, int rasconnstate, int dwError)
        {
            //rasconnstate 返回的是当前状态码
            //有兴趣的朋友可以假如自己的代码,它是个枚举,在c++中的结构如下
            /*
            typedef enum _RASCONNSTATE { 
                    RASCS_OpenPort = 0, 
                    RASCS_PortOpened, 
                    RASCS_ConnectDevice, 
                    RASCS_DeviceConnected, 
                    RASCS_AllDevicesConnected, 
                    RASCS_Authenticate, 
                    RASCS_AuthNotify, 
                    RASCS_AuthRetry, 
                    RASCS_AuthCallback, 
                    RASCS_AuthChangePassword, 
                    RASCS_AuthProject, 
                    RASCS_AuthLinkSpeed, 
                    RASCS_AuthAck, 
                    RASCS_ReAuthenticate, 
                    RASCS_Authenticated, 
                    RASCS_PrepareForCallback, 
                    RASCS_WaitForModemReset, 
                    RASCS_WaitForCallback,
                    RASCS_Projected, 
                #if (WINVER >= 0x400) 
                    RASCS_StartAuthentication,    // Windows 95 only 
                    RASCS_CallbackComplete,       // Windows 95 only 
                    RASCS_LogonNetwork,           // Windows 95 only 
                #endif 
                    RASCS_SubEntryConnected,
                    RASCS_SubEntryDisconnected,
                    RASCS_Interactive = RASCS_PAUSED, 
                    RASCS_RetryAuthentication, 
                    RASCS_CallbackSetByCaller, 
                    RASCS_PasswordExpired, 
                #if (WINVER >= 0x500)
                    RASCS_InvokeEapUI,
                #endif
                    RASCS_Connected = RASCS_DONE, 
                    RASCS_Disconnected 
                }RASCONNSTATE; 
            */
        }

        //时时检测网络
        private void CheckRasEvent()
        {
            int i;
            while (Keep)
            {
                i = GetConnect();
                if (i != 1)
                    if (rasDecoonect != null)
                    {
                        rasDecoonect(this, new Ras.RasDecoonectAgrs(i));
                        Keep = false;
                    }
            }
        }
    }

    public class RasDecoonectAgrs : System.EventArgs
    {
        public RasDecoonectAgrs(int i)
        {
            RasMeg = i;
        }
        public readonly int RasMeg;
    }
}

namespace WindowsApplication17
{
    /// <summary>
    /// Form1 的摘要说明。
    /// </summary>
}

该问题已经结贴 ,得分记录: snewxf (100)、

Contributors: FHL