running multiple threads with continous value returns (ping program)

277 views Asked by At

good day

I have taken up a project that as a bases needs insernt a command into cmd "ping x.x.x.x -t" and the program needs to return the output until a specified parameter

I am considering threads as my unterstanding in multithreading is limited, I am unable to continue without guidance

my ping class which recieves a string ip, adds it to a precompiled command string, etc.

I am aware of the built in ping class for this use, but I would prefer the "longer" method since i would gain valueble information/experience from this

main object class: ping

class ping
{
    Process proc;
    ProcessStartInfo psi;
    string ip_address;
    bool bStop = false;        

    public ping(string ip)
    {
        ip_address = ip;
    }

    public void StartPing()
    {
        string cmdInput;
        psi = new ProcessStartInfo(Environment.GetEnvironmentVariable("COMSPEC"));
        psi.RedirectStandardInput = true;
        psi.RedirectStandardOutput = true;

        psi.UseShellExecute = false;
        proc = Process.Start(psi);

        proc.StandardInput.WriteLine("ping " + ip_address + " -t");        

        cmdInput = proc.StandardOutput.ReadLine();
        cmdInput = proc.StandardOutput.ReadLine();
        cmdInput = proc.StandardOutput.ReadLine();
        cmdInput = proc.StandardOutput.ReadLine();
        cmdInput = proc.StandardOutput.ReadLine();
        cmdInput = proc.StandardOutput.ReadLine();
        while (bStop == false)
        {
            cmdInput = proc.StandardOutput.ReadLine();
            Console.WriteLine(returnPing(cmdInput));
        }
        proc.Close();
    }

    private string returnPing(string cmdInput)
    {
        int start, end;
        string ping;
        if (cmdInput.IndexOf("Reply") != -1 && cmdInput.IndexOf("time") != -1)
        {
            start = cmdInput.IndexOf("time=") + 5;
            end = cmdInput.IndexOf("ms");
            ping = cmdInput.Substring(start, end - start);
            return ping;

        }
        else return "-1";
    }

and thread_handler class, which manages mutliple instances of the ping method, please not the console.writeline is a temporary output which I will change in the future

class thread_handler
{
    string[] ipList;
    private IList<Thread> threadList;

    public thread_handler(string[] ip)
    {
        ipList = ip;
        threadList = new List<Thread>();
        createThreads();            
    }

    private void createThreads()
    {
        foreach (string item in ipList)
        {
            ping NewPing = new ping(item);
            Thread newPingThread = new Thread(NewPing.StartPing);
            newPingThread.IsBackground = true;
            newPingThread.Name = string.Format("{0}", item);
            threadList.Add(newPingThread);
        }
        startAllThreads();
    }

    private void startAllThreads()
    {
        foreach (Thread item in threadList)
        {
            item.Start();
        }
    }
}

Program

class Program
{
    static string[] ipList;
    static void Main(string[] args)
    {
        ipList = new String[3];
        readData();
        sendData();       
    }

    private static void sendData()
    {
        thread_handler thIp = new thread_handler(ipList);
    }

    private static void readData()
    {
        //use sll with name defintions and ip address's with metadata
        ipList[0] = "10.0.0.2";
        ipList[1] = "telkom_exchange";
        ipList[2] = "goo.gl";

    }

The aim of this program is (with gui changes in future) for a simple console with respective dimensions to constantly ping certain ip address's (we have ban infrastructure, thus program is for informative purposes), constantly updating on every ping reply

I do not want anyone to finish this program, I simply require assistance with running multiple instances (or maybe "threads") of this pinging, thus

each thread as it runs the "StartPing()" method, it should return an output, e.g. simply output the ping into the console, but it doesnt...

Output:

 The process tried to write to a nonexistent pipe. 
 The process tried to write to a nonexistent pipe.

then hangs

3

There are 3 answers

0
usr On BEST ANSWER

The way you read from the child process is not right. This is a surprisingly complicated task. I don't know why you are getting this specific error message but it sounds like it has to do with process standard output redirection. For example you have not redirected standard error.

I suggest you use one of the top voted snippets of stack overflow, to be found by: site:stackoverflow.com process RedirectStandardOutput. There are hundreds of such questions. Most solutions are subtly wrong.

This is a good checklist.

1
DrKoch On

You should use the ping class to execute a ping. This class allows you to control many details.

The call to ping.exe with Process.Start() involves way too much overhead and complicates things (as you experienced in your try)

0
CybeX On

As simple as it is, redirecting standard input and output did it, with a tweak or two, voila