go-signal - 解答
サーバー実装
// cmd/server/main.go
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
var (
currentByte byte
bitCount int
message []byte
)
func main() {
fmt.Printf("Server PID: %d\n", os.Getpid())
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGUSR1, syscall.SIGUSR2)
for sig := range sigChan {
handleSignal(sig)
}
}
func handleSignal(sig os.Signal) {
// ビットを設定
if sig == syscall.SIGUSR2 {
currentByte |= (1 << (7 - bitCount))
}
bitCount++
// 8ビット揃った
if bitCount == 8 {
if currentByte == 0 {
// 終端文字
fmt.Println(string(message))
message = nil
} else {
message = append(message, currentByte)
}
currentByte = 0
bitCount = 0
}
}
クライアント実装
// cmd/client/main.go
package main
import (
"fmt"
"os"
"strconv"
"syscall"
"time"
)
func main() {
if len(os.Args) < 3 {
fmt.Println("Usage: client <pid> <message>")
os.Exit(1)
}
pid, err := strconv.Atoi(os.Args[1])
if err != nil {
fmt.Println("Invalid PID")
os.Exit(1)
}
message := os.Args[2]
for _, char := range message {
sendByte(pid, byte(char))
}
sendByte(pid, 0) // 終端
}
func sendByte(pid int, b byte) {
for i := 7; i >= 0; i-- {
var sig syscall.Signal
if (b>>i)&1 == 1 {
sig = syscall.SIGUSR2
} else {
sig = syscall.SIGUSR1
}
syscall.Kill(pid, sig)
time.Sleep(100 * time.Microsecond)
}
}