1

There is a client and a server that communicates through stdio. I think I am basically confused about the stdin and stdout. I have some questions about the stdio.

  1. Does the server read the request from stdin or stdout where the client writes to?
  2. Does the server write response to stdin or stdout where the client can read?

Below is the code snippet of connection part on server side.

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()
}
bunny
  • 1,797
  • 8
  • 29
  • 58
  • 1
    You read from stdin, you write to stdout. There's really only one way to do it, and that what this code appears to do. What exactly is the problem you're encountering? – JimB Aug 03 '18 at 23:09
  • @JimB I understood this as "how does is this supposed to work together? i.e. actually pass data back and forth". Hopefully diane can chime in and add context. – matb Aug 03 '18 at 23:10
  • What I understand is any program always write to stdout and read from stdin and both client and server see the same stdin and stdout. What I am confused is if the server write response to stdout and how can client can read from stdin? Or the server write response to stdout and the client should read from stdout? Does the server and client sees the same stdin and stdout? – bunny Aug 03 '18 at 23:21
  • Every program *can* write to stdout and read from stdin, but doesn't have to. Each program has its own stdin and stdout (more background [here](https://stackoverflow.com/questions/3385201/confused-about-stdin-stdout-and-stderr?noredirect=1&lq=1). When you execute a program you can pass it in a stdin or direct a stdout somewhere else. E.g. `cat /etc/hosts | wc -l` you take stdout of `cat` program and feed it into stdin of `wc` program that reads the number of lines in `etc/hosts` file. – matb Aug 03 '18 at 23:48
  • My initial impression is that A: the program is redefining stdin/stdout, to be the request/response of the http message, or B: stdin/stdin is being used for debugging. I'm uncertain what "scoping" stdin/stdout have, so the former thought seems extremely risky with any multi-request/threaded app. Might be from a very basic tutorial that is trying to teach _only_ concepts? – Thymine Aug 03 '18 at 23:50
  • Yes, maybe what I don't know is the link part in the below answer. What I confused is if the server write response to stdout and how can client can read from stdin? I thought response server writes is all in stdout, server write nothing to stdin and how can client read it from stdin. Now I think I understand that usually server's stdout is linking to client's stdin. – bunny Aug 03 '18 at 23:55

1 Answers1

2

It's hard to say what this program is doing (as there's just a portion of it). Looks like you have an implementation of ReadWriteCloser that reads from stdin and writes to stdout (and a portion of a switch statement).

Generally any program can read from stdin and write to stdout (and stderr). You can link stdout of one program to stdin of other program with a pipe (e.g. client | server), but that's unidirectional. In your case, it sounds like you want client's stdin to go to server's stdout and vice versa. In local development, Unix sockets are usually used for that, but you might be able to create a named pipe (with mkfifo) like shown here.

Also, it might be easier to start with a super simple toy program, that doesn't include jsonrpc2 and any other packages.

I hope that helps!

matb
  • 851
  • 13
  • 23
  • 1
    Oh, I see! Usually the stdout of a program is linked to stdin of another program! For example, the stdout of the server links to stdin of the client and the stdin of the server links to the stdout of the client. In the above program, os.Stdin is actually a file("/dev/stdin") and os.Stdout is a file("/dev/stdout") . When you say link, do you mean server's stdin and client's stdout points to "/dev/stdin" and server's stdout and client's stdin points to "/dev/stdout"? – bunny Aug 03 '18 at 23:44
  • Yeah @diane, mental shortcut! By "link" I meant to say "use a pipe" - https://en.wikipedia.org/wiki/Pipeline_(Unix) – matb Aug 03 '18 at 23:54
  • Also, on Unix systems you can see file descriptors for std{in,out,err} for each process if you know your process PID with `ls /proc//fd/` :D, they will be numbered 0, 1 and 2 (everything else is other files or connections that your program opened) – matb Aug 03 '18 at 23:56
  • 1
    Thanks so much! The information you provide is very helpful. I will read more about pipe and file descriptors to understand it better. – bunny Aug 04 '18 at 00:03