Click here to Skip to main content
5,790,650 members and growing! (19,586 online)
Email Password   helpLost your password?
Web Development » ASP.NET » General     Intermediate

A web based dialup Internet application

By Dan_P

A web application to connect and disconnect from a dial up Internet session
C#, Windows, .NET 1.0, .NET 1.1, .NET, Visual Studio, ASP.NET, Dev

Posted: 29 Jun 2003
Updated: 6 Jul 2003
Views: 126,202
Bookmarked: 58 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
33 votes for this Article.
Popularity: 7.08 Rating: 4.66 out of 5
0 votes, 0.0%
1
1 vote, 3.0%
2
1 vote, 3.0%
3
4 votes, 12.1%
4
27 votes, 81.8%
5

Sample Image - webdialup.gif

Introduction

I recently changed my home network, basically I added a server to connect the network to the Internet. Unfortunately where I live we can't get broadband Internet, so the Internet connection server needs to dial into our ISP. I needed a simple way to connect, disconnect and see how long the connection has been up. Normally I would use terminal services to establish and view the connection, but since my wife also uses the Internet I needed another simpler way, one that even my wife can use. I built this web application, that displays the current connection's statistics or shows the phonebook entries so that the user can connect.

Using the code

I've wrapped up some of the RAS API's so I could use them with P/Invoke. They are:

  • RasEnumConnections
  • RasGetConnectionStatistics
  • RasHangUp
  • RasEnumEntries
  • InternetDial

I also had to create some structures that these API's could use:

  • RASCONN
  • RasEntryName
  • RasStats

I created a simple class called RASDisplay which has the following methods and properties:

Methods

  • int Connect(string Connection)
  • void Disconnect()

Properties

  • bool IsConnected
  • string ConnectionName
  • double BytesReceived
  • double BytesTransmitted
  • string[] Connections
  • string Duration

The RASDisplay class takes care of all the complexity of using the RAS API. If you not familiar with using the RAS API, you have to pass in the structure sizes, so the API knows which version you are working with. The constructor for this class uses the following code to set the above properties:

private string m_duration;
private string m_ConnectionName;
private string[] m_ConnectionNames;
private double m_TX;
private double m_RX;
private bool m_connected;
private IntPtr m_ConnectedRasHandle;

public RASDisplay()
{
    m_connected = true;

    RAS lpras = new RAS();
    RASCONN lprasConn = new RASCONN();            

    lprasConn.dwSize = Marshal.SizeOf(typeof(RASCONN));
    lprasConn.hrasconn = IntPtr.Zero;

    int lpcb = 0;
    int lpcConnections = 0;
    int nRet = 0;
    lpcb = Marshal.SizeOf(typeof(RASCONN));


    nRet = RAS.RasEnumConnections(ref lprasConn, ref lpcb, 
                                         ref lpcConnections);


    if(nRet != 0)
    {
        m_connected = false;
        return;
    }

    if(lpcConnections > 0)
    {
        RasStats stats = new RasStats();

        m_ConnectedRasHandle = lprasConn.hrasconn;
        RAS.RasGetConnectionStatistics(lprasConn.hrasconn, stats);

        m_ConnectionName = lprasConn.szEntryName;

        //Work out our duration 

        int Hours = 0;
        int Minutes = 0;
        int Seconds = 0;

        //The RasStats duration is in milliseconds

        Hours = ((stats.dwConnectDuration /1000) /3600);
        Minutes = ((stats.dwConnectDuration /1000) /60) - 
                                              (Hours * 60);
        Seconds = ((stats.dwConnectDuration /1000)) - 
                           (Minutes * 60) - (Hours * 3600);

        m_duration = Hours  +  " hours "  + Minutes + 
                " minutes " + Seconds + " secs";

        //set the bytes transferred and received

        m_TX = stats.dwBytesXmited;
        m_RX = stats.dwBytesRcved;

    }
    else
    {
        //we aren't connected

        m_connected = false;
    }

    //Find the names of the connections we could dial

    int lpNames = 1;
    int entryNameSize=Marshal.SizeOf(typeof(RasEntryName));
    int lpSize=lpNames*entryNameSize;
    RasEntryName[] names=new RasEntryName[lpNames];
    for(int i=0;i<names.Length;i++)
    {
        names[i].dwSize=entryNameSize;
    }

    uint retval = RAS.RasEnumEntries(null,null,names,
                                 ref lpSize,out lpNames);

    m_ConnectionNames = new string[lpNames];

    if(lpNames>0)
    {                
        for(int i=0;i<lpNames;i++)
        {
            m_ConnectionNames[i] = names[i].szEntryName;
        }
    }
}

The code to connect to the Internet uses the InternetDial WinInet API:

public int Connect(string sConnection)
{
    int intConnection = 0;
    uint INTERNET_AUTO_DIAL_UNATTENDED = 2;
    int retVal = RAS.InternetDial(IntPtr.Zero, sConnection,
            INTERNET_AUTO_DIAL_UNATTENDED,ref intConnection,0);
    return retVal;
}

The code to disconnect is very simple as well:

public void Disconnect()
{
    RAS.RasHangUp(m_ConnectedRasHandle);
}

The web application that uses the RASDisplay class looks like:

protected System.Web.UI.WebControls.Label lblName;
protected System.Web.UI.WebControls.Label lblDuration;
protected System.Web.UI.WebControls.Label lblTransmitted;
protected System.Web.UI.WebControls.DataGrid dgAllConnections;
protected System.Web.UI.HtmlControls.HtmlTable tblCurrentConnection;
protected System.Web.UI.WebControls.Button btnDisconnect;
protected System.Web.UI.WebControls.Label lblRecieved;

private void Page_Load(object sender, System.EventArgs e)
{
    if(!IsPostBack)
    {
        BindData();
    }
}

private void BindData()
{
    try
    {
        RASDisplay display = new RASDisplay();

        lblName.Text = display.ConnectionName;
        lblDuration.Text = display.Duration;
        lblRecieved.Text = display.BytesReceived.ToString();
        lblTransmitted.Text = display.BytesTransmitted.ToString();

        if(!display.IsConnected)
        {
            //show the table with stats

            tblCurrentConnection.Visible = false;
        }
        else
        {
            //show the tables with available connections

            dgAllConnections.Visible = false;
        }

        //bind the data

        dgAllConnections.DataSource = display.Connections;
        dgAllConnections.DataBind();

    }
    catch(Exception e){
        Response.Write(e.Message);
    }
}

protected void btnConnect_Click(object sender, EventArgs e)
{
    RASDisplay rasDisplay = new RASDisplay();

    //need to find the text in the first column of the datagrid

    Button btnSender = (Button) sender;
    DataGridItem ob =  (DataGridItem) btnSender.Parent.Parent;

    int ErrorVal = rasDisplay.Connect(ob.Cells[1].Text);

    if(ErrorVal != 0)
    {
        Response.Write(ErrorVal);
    }
    else
    {
        //redirect to the same page, so the display 

        //is refreshed with stats

        Response.Redirect("Default.aspx");
    }
}

protected void btnDisConnect_Click(object sender, EventArgs e)
{
    RASDisplay rasDisplay = new RASDisplay();
    rasDisplay.Disconnect();
    //redirect to the same page, so the display is 

    //refreshed with available connections

    Response.Redirect("Default.aspx");
}

The web application has a DataGrid that displays all the connections on the machine, this DataGrid only gets displayed if the computer isn't connected to the Internet. Otherwise a table with the connection's statistics gets displayed. The web page has a meta refresh tag, to keep the statistics up to date.

Know issues

Currently the Connect method calls InternetDial, this method takes the name of the connection. If this connection doesn't have a password saved, the call will fail. In a future version I'd like to change the way the application connects to the Internet, maybe using RASDial and have the application store the username and password for the user (or require them to enter it ? )

History

  • Article Created: 30/06/2003
  • Updated 7/7/2003 - Just a bug fix, if the user had more than one dialup internet phonebook, they might have some problems.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Dan_P


I've been programming for a few years now. I blog regularly at httpcode.
Occupation: Web Developer
Location: Australia Australia

Other popular ASP.NET articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 33 (Total in Forum: 33) (Refresh)FirstPrevNext
GeneralVery InformativememberMohammad Rastkar4:52 24 Jun '08  
GeneralDial up connnection in c#/.netmembersatheesh.yuva22:13 13 Apr '08  
QuestionGreat Job - Need help translating it to VB.NETmemberMember 443888612:11 3 Apr '08  
GeneralYou got 5memberDavid Bazan10:00 26 Feb '08  
GeneralCant disconnect neither get ANY exceptionmemberMuammar©3:30 16 Mar '07  
GeneralProblem in Getting Durationmemberss_hellhound7:06 16 Jan '06  
GeneralI LOVE YOUmembernaiemk21:02 21 Oct '05  
GeneralQuestion about Improvement of RASDisplay classmemberJonny Depp23:27 10 Aug '05  
GeneralError 691membersgomcres0:06 9 Sep '04  
GeneralRe: Error 691memberAhmad Maatouki11:50 9 Jan '07  
GeneralNeed help!memberRockman X70:42 25 Aug '04  
GeneralHook to dos windowmemberFrank59713:35 6 Aug '04  
GeneralUse of samememberdaniel doran6:27 10 Jun '04  
GeneralRasEnumConnections Errormemberbsargos10:44 31 Jan '04  
GeneralRe: RasEnumConnections ErrormemberMember 26767553:07 18 Apr '08  
GeneralVery well but problem with win98?sussarmink4:11 30 Jan '04  
GeneralGood job. Two questions :memberbsargos14:47 29 Jan '04  
GeneralNeed a small help....memberarun_br1:17 8 Dec '03  
GeneralDial-UP connectiomemberhzzz13:48 7 Dec '03  
GeneralRe: Dial-UP connectiomemberbenoityip3:33 8 Dec '03  
Generalgot this error...any ideas???memberavla0:18 26 Nov '03  
GeneralCRITICAL error when reusing object : no disconnectmemberUps1017:31 16 Oct '03  
GeneralRe: CRITICAL error when reusing object : no disconnectmemberUps1017:04 20 Oct '03  
GeneralEventmemberdaljv4:30 13 Aug '03  
GeneralGreat workmemberTili0:56 8 Jul '03