登录

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("未知操作")
		}
	}
}

加入讨论

登录或注册以发表评论