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")))
    }

}
Attila O.
  • 15,659
  • 11
  • 54
  • 84
user3324984
  • 349
  • 1
  • 5
  • 10
  • 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. – Ron Maupin Jul 26 '17 at 15:58

2 Answers2

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.

2pac
  • 73
  • 2
  • 6
siritinga
  • 4,063
  • 25
  • 38
  • 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. – user3324984 Apr 17 '14 at 18:47
  • 1
    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. – siritinga Apr 17 '14 at 18:49
  • 2
    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. – siritinga Apr 17 '14 at 18:57
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...
    }
user3215378
  • 547
  • 4
  • 4