13

Hi i'm attempted to learn some socket programming in golang, I'm following along with this tutorial

http://synflood.at/tmp/golang-slides/mrmcd2012.html#1

Here is the final result of the tutorial on one page. https://github.com/akrennmair/telnet-chat/blob/master/03_chat/chat.go

I'm confused on how to write the client side of this program, I create a connection and dial into the same port/ip as the server is running on but from there I don't know. I have read() and write() functions for the newly created connection but no idea where to delimit the read or anything. Considering the text input is handeled in the server I imagine I'd only need to do a read of some kind?

package main

import (
    "bufio"
    "fmt"
    "net"
    "os"
)

func main() {
    conn, err := net.Dial("tcp", "127.0.0.1:6000")
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    for {
        fmt.Println(bufio.NewReader(conn).ReadString([]byte("\n")))
    }

}
1
  • 1
    TCP is a peer-to-peer protocol, and it doesn't have clients or servers. The client/server concept is an application concept that has nothing to do with TCP. Commented Jul 26, 2017 at 15:58

2 Answers 2

12

bufio.NewReadershould be used only once, in your case, just before the for. For example connbuf := bufio.NewReader(conn). Then you can use ReadString on connbuf, that returns the string and maybe an error. For example:

connbuf := bufio.NewReader(conn)
for{
    str, err := connbuf.ReadString('\n')
    if err != nil {
        break
    }

    if len(str) > 0 {
        fmt.Println(str)
    }
}

I'm checking lenand err because ReadString may return data and an error (connection error, connection reset, etc.) so you need to check both.

Sign up to request clarification or add additional context in comments.

3 Comments

This works for getting to the first prompt however when the server is (I assume) executing bufc.ReadLine() it doesn't allow me to enter anything. This is the output I receive Welcome to chat room, What is your nickname?: but it hangs here not allowing input.
Yes, of course. It keeps reading and printing. If you need some interactivity, you can either stop the loop when detecting the prompt, or using goroutines, one for reading and another for writing.
If I understand what you want, you can use two goroutines after the connection has been established. One to read from the server, simply using io.Copy(os.Stdout, conn) and other for the other direction with io.Copy(conn, os.Stdin). This is completely asynchronous but it should be enough to get started.
1

Here is a simple solution if you want to read all received data.

    connbuf := bufio.NewReader(c.m_socket)
    // Read the first byte and set the underlying buffer
    b, _ := connbuf.ReadByte() 
    if connbuf.Buffered() > 0 {
        var msgData []byte
        msgData = append(msgData, b)
        for connbuf.Buffered() > 0 {
            // read byte by byte until the buffered data is not empty
            b, err := connbuf.ReadByte()
            if err == nil {
                msgData = append(msgData, b)
            } else {
                log.Println("-------> unreadable caracter...", b)
            }
        }
        // msgData now contain the buffered data...
    }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.