Go multiplexers

553 views
Skip to first unread message

Ramki...@hotmail.com

unread,
Aug 20, 2022, 4:31:34 PM8/20/22
to golang-nuts
Has anyone ever used a multiplexer? When creating a TCP server using multiplexer, I get an error [ERR] yamux: Invalid protocol version: 102 when using Telnet to connect to the server.

package main

import (
    "fmt"
    "net"

)

func main() {
    server()
}

func server() {

    listener, _ := net.Listen("tcp", "0.0.0.0:1113")
    for {

        // Accept a TCP connection
        conn, err := listener.Accept()
        if err != nil {
            panic(err)
        }

        // Setup server side of smux
        session, err := yamux.Server(conn, nil)
        if err != nil {
            panic(err)
        }

        // Accept a stream
        stream, err := session.Accept()
        if err != nil {
            panic(err)
        }
        fmt.Println("DPOO")

        // Listen for a message
        buf := make([]byte, 4)
        stream.Read(buf)
        stream.Close()
        session.Close()
    }
}

Sean Liao

unread,
Aug 20, 2022, 7:01:00 PM8/20/22
to golang-nuts
yamux uses its own protocol, it doesn't speak telnet

- sean

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/0034b133-79c3-47e7-853a-10282a5beed5n%40googlegroups.com.

Ramki...@hotmail.com

unread,
Aug 20, 2022, 11:23:46 PM8/20/22
to golang-nuts
Can  you tell me how I can figure out what it speaks?

Ramki...@hotmail.com

unread,
Aug 20, 2022, 11:30:39 PM8/20/22
to golang-nuts
Also, by chance do you know of an alternative that would provide multiple streams for a connection that happens different protocols or for TCP?

On Saturday, August 20, 2022 at 7:01:00 PM UTC-4 se...@liao.dev wrote:

Brian Candler

unread,
Aug 21, 2022, 4:09:51 AM8/21/22
to golang-nuts
> Can  you tell me how I can figure out what it speaks?

Finding that information doesn't appear to be hard:


"The full specification for Yamux is provided in the spec.md file. It can be used as a guide to implementors of interoperable libraries."

> Also, by chance do you know of an alternative that would provide multiple streams for a connection that happens different protocols or for TCP?

Here are some things you can look at:

* http/2 -- and other protocols which run on top of it, e.g. grpc.
* ssh. You can open multiple sessions over the same connection, and you can do TCP port forwarding. The command-line ssh client also supports port forwarding using the SOCKS protocol (-D flag).
* message routing protocols like nats.io, nanomsg, zeromq
SCTP
BEEP (that is very old-school)

It really depends what your application requirements are.  It might be simplest for your application to do its own multiplexing.

TheDiveO

unread,
Aug 21, 2022, 5:17:37 AM8/21/22
to golang-nuts
do you even need a multiplexer? The common patten is to run Accept in a loop that simply starts a new Go routine for every new accepted connection. You only need a multiplexer of your application protocol needs multiplexing inside an established TCP connection, either because there are multiple destinations or multiple streams inside a single connection.

Ramki...@hotmail.com

unread,
Aug 21, 2022, 7:32:27 AM8/21/22
to golang-nuts
My original issue is when using splice with  io.Copy (example below), for me to regain access to conn, In a different go routine, I use remote.Close() which ends the one of io.Copy commands but, the second io.Copy ends when conn sends a new packet. The error  use of closed network connection ends the io.Copy and every new packet conn sends, I can get with conn.Read() but the previous one is lost. 
I thought may be a multiplexer may help if I hope multiple streams for conn, I can end the splice while still reading all data with conn.Read() with a different stream.  

io.Copy(conn, remote) 
go io.Copy(remote, conn)



Brian Candler

unread,
Aug 21, 2022, 8:15:21 AM8/21/22
to golang-nuts
"conn" is just a value, you can pass it around.  However, if you're sharing it between multiple goroutines you need to be careful, i.e. you need to synchronize properly. The synchronization solutions are very specific to your application: e.g. you could wait for that goroutine to finish with a sync.WaitGroup, or the goroutine could send you a message on a channel when it's done.

I don't know why you want to use multiple goroutines on the *same* connection though.  (If you have multiple clients, they will open their own TCP connections, which will be different "conn" objects).

What you're now describing sounds very unlike "multiplexing", which I would normally understand to be sending multiple independent sessions down a single connection.

TheDiveO

unread,
Aug 21, 2022, 10:36:02 AM8/21/22
to golang-nuts
Looks like a TCP proxy or forwarder to me. For full duplex communicating you need two go routines per connection/session. And yes, needs something like a wait group for synchronization in order to handle half- closed connections properly, for client and server variants.
Reply all
Reply to author
Forward
0 new messages