2014-04-17 22 views
8

Cześć jestem próbowali nauczyć się programowania gniazd w golang, Obserwuję wraz z tym tutorialuTworzenie klienta TCP w golang

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

Oto ostateczny wynik samouczka na jednej stronie . https://github.com/akrennmair/telnet-chat/blob/master/03_chat/chat.go

Jestem zdezorientowany, jak napisać stronę klienta tego programu, tworzę połączenie i dzwonię do tego samego portu/ip, na którym działa serwer, ale z tego nie wiem. Mam funkcje read() i write() dla nowo utworzonego połączenia, ale nie mam pojęcia, gdzie ograniczać czytanie lub cokolwiek. Biorąc pod uwagę, że dane wprowadzane są do serwera, wyobrażam sobie, że potrzebuję tylko jakiegoś rodzaju czytania?

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

} 
+0

TCP jest protokołem peer-to-peer i nie ma klientów ani serwerów. Koncepcja klient/serwer to koncepcja aplikacji, która nie ma nic wspólnego z TCP. –

Odpowiedz

11

bufio.NewReader powinny być używane tylko raz, w danym przypadku, tuż przed for. Na przykład connbuf := bufio.NewReader(conn). Następnie możesz użyć ReadString na connbuf, który zwraca ciąg znaków i być może błąd. Na przykład:

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

mam sprawdzanie len i errReadString ponieważ może powrócić danych i błąd (błąd połączenia, resetowania połączenia, itd.), Więc trzeba sprawdzić oba.

+0

To działa, aby dostać się do pierwszej zachęty, jednak gdy serwer jest (zakładam) wykonywanie 'bufc.ReadLine()' nie pozwala mi wprowadzić niczego. To jest wynik, który otrzymuję "Witamy w pokoju rozmów, Jaki jest twój pseudonim?:" Ale zawiesza się tutaj, nie zezwalając na wprowadzanie danych. – user3324984

+0

Tak, oczywiście. Utrzymuje czytanie i drukowanie. Jeśli potrzebujesz interaktywności, możesz zatrzymać pętlę po wykryciu monitu lub używając goroutinów, jednego do czytania i drugiego do pisania. – siritinga

+1

Jeśli rozumiem, czego chcesz, możesz użyć dwóch goryntów po nawiązaniu połączenia. Jeden do odczytu z serwera, po prostu używając 'io.Copy (os.Stdout, conn)' i innego dla innego kierunku z 'io.Copy (conn, os.Stdin)'. Jest to całkowicie asynchroniczne, ale powinno wystarczyć. – siritinga

0

Oto proste rozwiązanie, jeśli chcesz przeczytać wszystkie odebrane dane.

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... 
    }