go stdin stdout 双交互程序 (参考UCI)
Coding
2025-11-24 23:13:06
UCI 是通用象棋接口 ,觉得比较有意思的点是因为 象棋引擎 在windows 上是一个一个exe可执行程序,gui程序和引擎之间的通讯是通过 标准输入输出进行交互的,也是一个比较有意思的加载方式。(不同于动态连接库或者socket)
client
func runInputClient(_ *cobra.Command, args []string) {
type Request struct {
Action string `json:"action"`
}
cmd := exec.Command("gopt", "demo", "input") // 替换为你的交互式程序可执行文件名
stdinPipe, stdinPipeErr := cmd.StdinPipe()
if stdinPipeErr != nil {
fmt.Println(stdinPipeErr)
return
}
stdoutPipe, stdoutPipeErr := cmd.StdoutPipe()
if stdoutPipeErr != nil {
fmt.Println(stdoutPipeErr)
return
}
err := cmd.Start()
if err != nil {
fmt.Println(err)
return
}
go func() {
defer stdinPipe.Close()
encoder := json.NewEncoder(stdinPipe)
decoder := json.NewDecoder(os.Stdin)
for {
var req Request
err := decoder.Decode(&req)
if err != nil {
fmt.Println(err)
break
}
err = encoder.Encode(req)
if err != nil {
fmt.Println(err)
break
}
}
}()
decoder := json.NewDecoder(stdoutPipe)
for {
var response string
err := decoder.Decode(&response)
if err != nil {
if err != io.EOF {
fmt.Println(err)
}
break
}
fmt.Println("Response:", response)
}
cmd.Wait()
}
server
func runInputServer(_ *cobra.Command, _ []string) {
// {"action":"get"}
type Request struct {
Action string `json:"action"`
}
decoder := json.NewDecoder(os.Stdin)
encoder := json.NewEncoder(os.Stdout)
for {
var req Request
err := decoder.Decode(&req)
if err != nil {
fmt.Println(err)
return
}
switch req.Action {
case "get":
// 这里可以进行相关操作,根据需要获取所需数据
response := "这是要获取的内容"
err = encoder.Encode(response)
if err != nil {
fmt.Println(err)
return
}
case "quit":
return
default:
fmt.Println("未知操作")
}
}
}