Creating a TCP client in golang
Asked Answered
I

2

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

}
Indiscipline answered 17/4, 2014 at 18:5 Comment(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.Rental
R
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.

Rafat answered 17/4, 2014 at 18:33 Comment(3)
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.Indiscipline
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.Rafat
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.Rafat
A
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...
    }
Ailanthus answered 26/7, 2017 at 15:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.