You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Go语言中将控制信号转换为ASCII字节十六进制编码

Great question! The key here is to split the problem into two clear, maintainable steps: mapping the OS signals you care about to their corresponding ASCII control bytes, then converting those bytes to hexadecimal strings on the fly. This avoids hardcoding hex values and makes it easy to extend later.

How It Works Under the Hood

First, let's recall the relationship between Ctrl+key combinations and ASCII control codes:

  • For most Ctrl+letter combinations (like Ctrl+C, Ctrl+Z), the control code is the uppercase letter's ASCII value minus 0x40. For example:
    • 'C' is 0x43 → 0x43 - 0x40 = 0x03 (Ctrl+C)
    • 'Z' is 0x5A → 0x5A - 0x40 = 0x1A (Ctrl+Z)
  • Special cases like Ctrl+\ map directly to 0x1C (this doesn't follow the letter rule, so we'll handle it explicitly).

Implementation Steps & Example Code

Here's how to implement this in Go:

  1. Create a signal-to-control-byte map: Instead of hardcoding hex strings, map each OS signal to its raw ASCII control byte. This keeps your logic flexible.
  2. Listen for target signals: Use os/signal to catch SIGINT (Ctrl+C), SIGTSTP (Ctrl+Z), and SIGQUIT (Ctrl+).
  3. Convert bytes to hex: When a signal is received, fetch the control byte, then use Go's standard encoding/hex package to convert it to a hex string.
  4. Send to WebSocket: Transmit the hex string over your WebSocket connection.
package main

import (
	"encoding/hex"
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"github.com/gorilla/websocket"
)

func main() {
	// Establish your WebSocket connection first (example placeholder)
	// conn, _, err := websocket.DefaultDialer.Dial("ws://your-websocket-endpoint", nil)
	// if err != nil {
	//     panic(fmt.Errorf("failed to dial WS: %w", err))
	// }
	// defer conn.Close()

	// Map OS signals to their corresponding ASCII control bytes
	signalToCtrlByte := map[os.Signal]byte{
		syscall.SIGINT:  0x03, // Ctrl+C
		syscall.SIGTSTP: 0x1A, // Ctrl+Z
		syscall.SIGQUIT: 0x1C, // Ctrl+\
		// Add more signals here if needed (e.g., SIGTERM for other interrupts)
	}

	// Set up signal listening
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTSTP, syscall.SIGQUIT)

	// Handle incoming signals in a goroutine
	go func() {
		for sig := range sigChan {
			ctrlByte, exists := signalToCtrlByte[sig]
			if !exists {
				fmt.Printf("Unhandled signal: %v\n", sig)
				continue
			}

			// Convert control byte to hexadecimal string
			hexStr := hex.EncodeToString([]byte{ctrlByte})
			fmt.Printf("Caught signal %v → sending hex: %s\n", sig, hexStr)

			// Send hex string over WebSocket
			if err := conn.WriteMessage(websocket.TextMessage, []byte(hexStr)); err != nil {
				fmt.Printf("Failed to send WS message: %v\n", err)
				return
			}
		}
	}()

	// Keep the main goroutine alive
	select {}
}

Why This Is Better Than Hardcoding

  • Maintainability: Adding a new signal only requires adding one line to the map (e.g., syscall.SIGTERM: 0x18 for Ctrl+X) instead of modifying hardcoded hex strings.
  • Flexibility: If you ever need to send the raw control byte (instead of hex), you can skip the hex conversion step entirely—no refactoring needed.
  • Clarity: Separating the signal-to-byte mapping from the hex conversion makes your code easier to read and debug.

Notes for Cross-Platform Use

If you're targeting Windows, note that some signals (like SIGTSTP) behave differently or aren't supported. You may need to adjust the signal set and mappings based on the OS, but this approach works seamlessly on Linux/macOS.

内容的提问来源于stack exchange,提问作者kittu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:25:05