CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13

Thread: netstat

  1. #1
    Join Date
    Mar 2003
    Location
    Hamilton, Ontario, Canada
    Posts
    12

    netstat

    Does any one have a suggestion for an easy way to implement the netstat command using C#? (netstat displays all current open connections) I thought about using sockets, and scanning each port but that seems it would take too long to scan (also not really sure how to even start coding that )

    Is there a way in C# to call the already implemented command (from DOS) and display the output in a listbox? Or does anyone have any other suggestions on how to implement this?

    Thanks

    (I'm still very new to C# so I appreciate all the input, hopefully in a bit of time I will actually acquire enough experience and knowledge, to contribute to this forum )

  2. #2
    Join Date
    Aug 2002
    Location
    Germany, Berlin
    Posts
    60
    net stat is a local command which you can execute on your machine. If you want to distribute this command to all machines, you usually do it from a server, just providing all clients by DNS name.
    You should do marshalling, but u don't need sockets. The problem to get the return message, I just can suggest to redirect the output stream. But this is still a unsolved problem in my project, too.

  3. #3
    Join Date
    Dec 2000
    Location
    Slovakia
    Posts
    1,043
    Don't know exectelly your needs, however I sugest you to check api functions GetTcpTable and GetUdpTable in MSDN... You can really easily get tcp and udp connections on your computer.

    Regarding calling external prog (netstat) from your C# code and redirecting its output look on following code:
    Code:
    string sCommand = "netstat";
    string sArgs = "";
    System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo (sCommand, sArgs);
    
    psi.UseShellExecute = false;
    psi.RedirectStandartOutput = true;
    
    System.Diagnostics.Process proc = null;
    proc = System.Diagnostics.Process.Start(psi);
    proc.WaitForExit();
    
    // Read the first 4 lines. They don't contain any information we need to get
    for (int i = 0; i < 4; i++)
        proc.StandartOutput.ReadLine();
    
    while (true)
    {
        string strLine = proc.StandartOutput.ReadLine();
        if (strLine == null)
            break;
    
        // Analyze the line 
        // Lina is in following structure:
        // Protocol (TCP/UDP)   Local Address(host:port) Foreign Address(host:port) State(ESTABLISHED, ...)
    }
    martin

    martin

  4. #4
    Join Date
    Mar 2003
    Location
    Hamilton, Ontario, Canada
    Posts
    12
    Thank you both for the input. (Especially Martin. I didn't expect some one to put up code, and it is much appreciated). For now I will just try to use the code you've posted, and in the next couple days I will read up about GetTcpTable and GetUdpTable (I think coding it myself would be more beneficial to me). Any ways, thank you again.


    Eric

  5. #5
    Join Date
    Mar 2003
    Location
    Hamilton, Ontario, Canada
    Posts
    12
    Martin, just a couple quick questions:

    1. If using the already implemented netstat command (dos), is it possible to execute it, with out the application actually invoking a DOS window? (When my application runs, it quickly opens up a DOS window, and I don't think this looks very professional nor is it very functional)

    2. I looked up some info on the api functions GetTcpTable and GetUdpTable, and I would like to implement this method. However I'm not sure what namespace to use in C#. Is it possible to use this in C# .NET environment or is this something for C++ ?

    Thanks
    Eric

  6. #6
    Join Date
    Dec 2000
    Location
    Slovakia
    Posts
    1,043
    1.)
    Sure there are some method how to hide the commandpromt window... However I didn't solve such problem, so I don't have clear solution in my memory.

    One possible solution, with a little of overwork, could be that you create a windows service. You can communication with that service using .net remoting. Service will call netstat command. Then it reads the result of command, translates it into some structure defined by use and returns that to the caller.
    When you disable interactivity with desktop in the service control manager for that service, command prompt window will not appear...

    I know, it is not a clear solution, however I don't have a time to search for "real" solution.

    2.)
    I'm afraid, GetTcpTable&GetUdpTable functions are not part of .net framework class library. You need to use InteropServices and import these functions into you c# application. Then you can call them directly from c#. It may look following:
    Code:
    using System.Runtime.InteropServices;
    
    public struct TCPTableEntry
    {
        public int state;
        public int localaddr;
        public int localport;
        public int remoteaddr;
        public int remoteport;
    }
    
    public class SomeClass
    {
        [DllImport("C:\\Winnt\\System32\\Iphlpapi.dll")]
        public static extern int GetTcpTable(byte[] pTcpTable, out int pdwSize, bool bOrder);
    
        protected string GetRemoteIPAddress(TCPTableEntry entry)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.AppendFormat("{3}.{2}.{1}.{0}", (entry.remoteaddr >> 24) & 255, 
                (entry.remoteaddr >> 16) & 255, (entry.remoteaddr >> 8) & 255, entry.remoteaddr & 255);
            return sb.ToString();
        }
    
        protected string GetLocalIPAddress(TCPTableEntry entry)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.AppendFormat("{3}.{2}.{1}.{0}", (entry.localaddr >> 24) & 255, 
               (entry.localaddr >> 16) & 255, (entry.localaddr >> 8) & 255, entry.localaddr & 255);
            return sb.ToString();
        }
    
        protected string GetRemotePortNumber(TCPTableEntry entry)
        {
            return entry.remoteport.ToString();
        }
    
        protected string GetLocalPortNumber(TCPTableEntry entry)
        {
            return entry.localport.ToString();
        }
    
        void GetTcpConnections()
        {
            byte[] buffer = new byte[20000]; // Start with 20.000 bytes left for information about tcp table
            int pdwSize = 20000;
            int res = GetTcpTable(buffer, out pdwSize, false);
            if (res != 0)
            {
                  buffer = new byte[pdwSize];
                  res = GetTcpTable(buffer, out pdwSize, false);
                  if (res != 0)
                      return;     // Error. You should handle it
            }
    
            int nOffset = 0;
            int nNumber = buffer[nOffset] + (((int)buffer[nOffset+1])<<8) + 
                (((int)buffer[nOffset+2])<<16) + (((int)buffer[nOffset+3])<<24);
            nOffset += 4;
    
            for (int i = 0; i < nNumber; i++)
            {
                TCPTableEntry entry = new TCPTableEntry();
                entry.state = buffer[nOffset] + (((int)buffer[nOffset+1])<<8) + 
                    (((int)buffer[nOffset+2])<<16) + (((int)buffer[nOffset+3])<<24);
    
                entry.localaddr = buffer[nOffset] + (((int)buffer[nOffset+1])<<8) + 
                    (((int)buffer[nOffset+2])<<16) + (((int)buffer[nOffset+3])<<24);
                nOffset += 4;
                entry.localport = (((int)buffer[nOffset])<<8) + (((int)buffer[nOffset+1])) + 
                     (((int)buffer[nOffset+2])<<24) + (((int)buffer[nOffset+3])<<16);
                nOffset += 4;
                entry.remoteaddr = buffer[nOffset] + (((int)buffer[nOffset+1])<<8) + 
                    (((int)buffer[nOffset+2])<<16) + (((int)buffer[nOffset+3])<<24);
                nOffset += 4;		
                entry.remoteport = (((int)buffer[nOffset])<<8) + (((int)buffer[nOffset+1])) + 
                    (((int)buffer[nOffset+2])<<24) + (((int)buffer[nOffset+3])<<16);
                nOffset += 4;
    
                string sRemoteIp = GetRemoteIpAddress(entry);
                string sRemotePort = GetRemotePortNumber(entry);
                string sLocalIp = GetLocalIpAddress(entry);
                string sLocalPort = GetLocalPort(entry);
    
                // Now you can write the tcp table row somewhere
                Console.WriteLine("Local: {1}:{2}  Remote: {3}:{4}   State: {5}", 
                     sLocalIp, sLocalPort, sRemoteIp, sRemotePort, entry.state.ToString());
            }
        }
    }
    I wrote this code just by the hand, so appologize if there are some errors...

  7. #7
    Join Date
    Jul 2002
    Location
    .NET 2.0/.NET 3.0/.NET 3.5 VS2005/VS2008
    Posts
    284
    GREAT CODE !!!

    I will use this in my app too
    WM.

    What about weapons of mass construction?

  8. #8
    Join Date
    Aug 2002
    Location
    Germany, Berlin
    Posts
    60
    Originally posted by MartinL
    1.)
    Sure there are some method how to hide the commandpromt window... However I didn't solve such problem, so I don't have clear solution in my memory.

    One possible solution, with a little of overwork, could be that you create a windows service. You can communication with that service using .net remoting. Service will call netstat command. Then it reads the result of command, translates it into some structure defined by use and returns that to the caller.
    When you disable interactivity with desktop in the service control manager for that service, command prompt window will not appear...

    I know, it is not a clear solution, however I don't have a time to search for "real" solution.
    TO Hide:

    using "cmd /C netstat" will actually close the cmd-window, but it is still visible for a short time.

    Another possibility is to start the cmd via a WMIClient, which is very much code for just a local cmd.

    Nevertheless, your code sample is great.

  9. #9
    Join Date
    Nov 2002
    Location
    Singapore
    Posts
    1,890
    Martin is working Hard these days


    good work Martin,

    - Paresh
    - Software Architect

  10. #10
    Join Date
    Mar 2003
    Location
    Hamilton, Ontario, Canada
    Posts
    12

    Talking

    Wow, Thank you for all the help. Martin, I really appreciate you taking the time to post that code. I will try it out later tonight.

    This is one amazing forum. I am very impressed and I'm sure glad I found it.



    Eric

  11. #11
    Join Date
    Nov 2002
    Location
    Singapore
    Posts
    1,890
    well it has lots of post/edit/manage etc options which I think no other forums has.
    - Software Architect

  12. #12
    Join Date
    May 2007
    Posts
    2

    Red face Re: netstat

    Hi,

    This is my first post to this forum. I don't know if there is any other thread that have already answered this. I searched but couldn't find any. Please help me with pointers if know of.

    Basically my requirement is to Open a TCP listener from a port not used by anybody. Clients comes to know about this port through some file and connets. I don't want my code to be dependent on any DLL or dos command.

    Is there no pure C# way of doing this thing? Like without having to refer to DLLs or without using any DOS command? Can we have this somehow through TcpStatistics or anything related?

    I am not very fluent with C# libraries. Please help.

    -- Bikram

  13. #13
    Join Date
    May 2007
    Posts
    2

    Re: netstat

    Hi,

    I got it, I guess. It is there in msdn "ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_fxsamples/html/303dd303-ee06-4abc-bda1-41c0b87fcf9d.htm"

    Also the code below can be a demonstration for TCP:

    using System;
    using System.Net.NetworkInformation;
    using System.Net;

    namespace TesterConsoleProject
    {
    public class Program
    {
    public static void Main(string[] args)
    {
    IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();

    IPEndPoint[] epList = properties.GetActiveTcpListeners();
    TcpConnectionInformation[] tcpInfoList = properties.GetActiveTcpConnections();

    foreach (IPEndPoint ep in epList)
    {
    Console.WriteLine(ep.Address.ToString() + ":" + ep.Port.ToString("d"));
    }
    foreach (TcpConnectionInformation tcpInfo in tcpInfoList)
    {
    Console.WriteLine(tcpInfo.LocalEndPoint.Address.ToString() + ":" +
    tcpInfo.LocalEndPoint.Port.ToString("d")
    + " -> " +
    tcpInfo.RemoteEndPoint.Address.ToString() + ":" +
    tcpInfo.RemoteEndPoint.Port.ToString("d"));
    }
    }
    }
    }

    It compiles and runs...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured