Simple Client+Server invoked with signals
dotnet-10 makes prototyping and playing around very easy (using
dotnet run single-file.cs)
In this example:
- using just
stdinandstdoutwith signal - server run, then waits for a signal
SIGUSR1 = 10 - on signal
- runs
client - writes Hello,World
- reads stdout and echos
- runs
- client
- read stdin and echos to stdout with a prefix
Server
#!/bin/env -S dotnet run
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
// $ man signal
[DllImport("libc")]
static extern void signal(int signum, Action handler);
static void HandleSIGUSR1()
{
Console.WriteLine("SIGUSR1 received!");
var proc = Process.Start(
new ProcessStartInfo("./client.cs")
{
RedirectStandardInput = true,
RedirectStandardOutput = true,
});
Thread.Sleep(100);
if (proc != null)
{
Console.WriteLine($"Started: {proc.Id}.. waiting");
var task = Task.Run( ()=>
{
proc.StandardInput.WriteLine("Hello");
Thread.Sleep(100);
proc.StandardInput.WriteLine("World");
Thread.Sleep(100);
proc.StandardInput.Close();
});
while (proc.StandardOutput.ReadLine() is {} outp)
{
Console.WriteLine($"| {outp}");
}
}
Console.WriteLine("Closed");
Console.WriteLine();
}
Console.WriteLine($"server.cs -- PID={Environment.ProcessId}");
Console.WriteLine("");
Console.WriteLine(
"""
Waiting for SIGUSR1...
To send the signal, run:
$ kill -SIGUSR1 `pidof server`
""");
signal(/* SIGUSR1 */ 10, HandleSIGUSR1);
while (true)
{
Thread.Sleep(200);
}
Client
#!/bin/env -S dotnet run
Console.WriteLine($">client.cs -- PID={Environment.ProcessId}");
Console.WriteLine(">Another");
while(Console.ReadLine() is {} line)
{
Console.WriteLine($" <-> {line}");
}
Console.WriteLine(">bye");
Result
