【问题标题】:server client connection through stdio通过 stdio 连接服务器客户端
【发布时间】:2018-08-03 22:57:10
【问题描述】:

有一个客户端和一个服务器通过 stdio 进行通信。我想我基本上对标准输入和标准输出感到困惑。我对 stdio 有一些疑问。

  1. 服务器是否从客户端写入的标准输入或标准输出读取请求?
  2. 服务器是否将响应写入客户端可以读取的标准输入或标准输出?

下面是服务器端连接部分的代码sn-p。

case "stdio":
    log.Println("server: reading on stdin, writing on stdout")
    <-jsonrpc2.NewConn(context.Background(), jsonrpc2.NewBufferedStream(stdrwc{}, jsonrpc2.VSCodeObjectCodec{}), handler, connOpt...).DisconnectNotify()
    log.Println("connection closed")
    return nil


type stdrwc struct{}

func (stdrwc) Read(p []byte) (int, error) {
    return os.Stdin.Read(p)
}

func (stdrwc) Write(p []byte) (int, error) {
    return os.Stdout.Write(p)
}

func (stdrwc) Close() error {
    if err := os.Stdin.Close(); err != nil {
        return err
    }
    return os.Stdout.Close()
}

【问题讨论】:

  • 你从标准输入读取,你写入标准输出。实际上只有一种方法可以做到这一点,并且该代码似乎可以做到这一点。您遇到的具体问题是什么?
  • @JimB 我将其理解为“这应该如何协同工作?即实际上来回传递数据”。希望黛安可以插话并添加上下文。
  • 我的理解是任何程序总是写入标准输出并从标准输入读取,并且客户端和服务器都看到相同的标准输入和标准输出。我感到困惑的是,如果服务器向标准输出写入响应,客户端如何从标准输入读取?或者服务器对标准输出的写响应和客户端应该从标准输出读取?服务器和客户端是否看到相同的标准输入和标准输出?
  • 每个程序可以写入标准输出并从标准输入读取,但不是必须的。每个程序都有自己的标准输入和标准输出(更多背景here。当你执行一个程序时,你可以在标准输入中传递它或在其他地方引导标准输出。例如cat /etc/hosts | wc -l你从cat程序中获取标准输出并将其输入wc 程序的标准输入,用于读取etc/hosts 文件中的行数。
  • 我的第一印象是A:程序正在重新定义stdin/stdout,作为http消息的请求/响应,或者B:stdin/stdin用于调试。我不确定“范围”标准输入/标准输出有什么,所以前一种想法对于任何多请求/线程应用程序来说似乎都极具风险。可能来自试图教授概念的非常基本的教程?

标签: go stdout stdin


【解决方案1】:

很难说这个程序在做什么(因为它只是其中的一部分)。看起来您有一个 ReadWriteCloser 的实现,它从标准输入读取并写入标准输出(以及 switch 语句的一部分)。

通常任何程序都可以从标准输入读取并写入标准输出(和标准错误)。您可以使用管道(例如client | server)将一个程序的标准输出链接到其他程序的标准输入,但这是单向的。在您的情况下,听起来您希望客户端的标准输入转到服务器的标准输出,反之亦然。在本地开发中,通常使用 Unix 套接字,但您可以创建一个命名管道(使用 mkfifo),如 here 所示。

另外,从一个不包括jsonrpc2 和任何其他包的超级简单的玩具程序开始可能会更容易。

希望对你有帮助!

【讨论】:

  • 哦,我明白了!通常一个程序的标准输出链接到另一个程序的标准输入!例如,服务器的标准输出链接到客户端的标准输入,服务器的标准输入链接到客户端的标准输出。在上面的程序中, os.Stdin 实际上是一个文件(“/dev/stdin”),而 os.Stdout 是一个文件(“/dev/stdout”)。当您说链接时,您的意思是服务器的标准输入和客户端的标准输出指向“/dev/stdin”并且服务器的标准输出和客户端的标准输入指向“/dev/stdout”?
  • 是的@diane,心理捷径! “链接”是指“使用管道”-en.wikipedia.org/wiki/Pipeline_(Unix)
  • 此外,在 Unix 系统上,如果您知道进程 PID 为 ls /proc/&lt;PID&gt;/fd/ :D,您可以看到每个进程的 std{in,out,err} 的文件描述符,它们将编号为 0、1和 2(其他都是你的程序打开的其他文件或连接)
  • 非常感谢!您提供的信息非常有帮助。我将阅读有关管道和文件描述符的更多信息以更好地理解它。
猜你喜欢
  • 2017-05-08
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多