2010-02-16 60 views
4

我正在尝试学习go语言,并且正在编写一个简单的echo服务器。尽管如此,我仍然很难做到这一点。无法从套接字中读取

func listen(server string) { 
    var buf []byte 

    listener, ok := net.Listen("tcp", server) 
    if ok != nil { 
     fmt.Fprintf(os.Stderr, "Could not listen on socket: %s\n", ok.String()) 
     return 
    } 
    conn, ok := listener.Accept() 
    if ok != nil { 
     fmt.Fprintf(os.Stderr, "Could not accept connection on socket: %s\n", ok.String()) 
     return 
    } 

    writelen, ok := conn.Write(strings.Bytes("Ready to receive\n")) 
    if ok != nil { 
     fmt.Fprintf(os.Stderr, "Could not write to socket: %s\n", ok.String()) 
    } else { 
     fmt.Printf("Wrote %d bytes to socket\n", writelen) 
    } 

    for ;; { 
     readlen, ok := conn.Read(buf) 
     if ok != nil { 
      fmt.Fprintf(os.Stderr, "Error when reading from socket: %s\n", ok.String()) 
      return 
     } 
     if readlen == 0 { 
      fmt.Printf("Connection closed by remote host\n") 
      return 
     } 

     fmt.Printf("Client at %s says '%s'\n", conn.RemoteAddr().String(), buf) 
    } 
} 

我得到以下输出从这个函数:

[[email protected] ~/src/go/echo_server] ./6.out 1234 
Using port 1234 
Wrote 17 bytes to socket 
Error when reading from socket: EOF 

这是我看到在客户端上:

[[email protected] ~] telnet 127.0.0.1 1234 
Trying 127.0.0.1... 
Connected to 127.0.0.1. 
Escape character is '^]'. 
Ready to receive 
Connection closed by foreign host. 

任何帮助,将不胜感激(或指针资源;关于套接字API的go文档留下了一些不足之处)。

感谢,

弥敦道

回答

8

在你的榜样,BUF需要有一定的规模。你已经声明它是一个0长度的片。

声明为:

var buf = make([]byte, 1024) 
+0

这样做,谢谢! 我想我还没有完全理解切片......我会再读一遍。 – Nathan 2010-02-16 15:11:24

2

当然,如果你想学,不如把它写自己,但是,如果有帮助,这里是在走我自己的回声服务器。

package main 

import (
    "net"; 
    "os"; 
    "fmt"; 
) 

func handle(conn *net.TCPConn) { 
    fmt.Printf("Connection from %s\n", conn.RemoteAddr()); 
    message := make([]byte, 1024); 
    // TODO: loop the read, we can have >1024 bytes 
    n1, error := conn.Read(message); 
    if error != nil { 
     fmt.Printf("Cannot read: %s\n", error); 
     os.Exit(1); 
    } 
    n2, error := conn.Write(message[0:n1]); 
    if error != nil || n2 != n1 { 
     fmt.Printf("Cannot write: %s\n", error); 
     os.Exit(1); 
    } 
    fmt.Printf("Echoed %d bytes\n", n2); 
    conn.Close(); // TODO: wait to see if more data? It would be better with telnet... 
} 

func main() { 
    listen := ":7"; 
    addr, error := net.ResolveTCPAddr(listen); 
    if error != nil { 
     fmt.Printf("Cannot parse \"%s\": %s\n", listen, error); 
     os.Exit(1); 
    } 
    listener, error := net.ListenTCP("tcp", addr); 
    if error != nil { 
     fmt.Printf("Cannot listen: %s\n", error); 
     os.Exit(1); 
    } 
    for { // ever... 
     conn, error := listener.AcceptTCP(); 
     if error != nil { 
      fmt.Printf("Cannot accept: %s\n", error); 
      os.Exit(1); 
     } 
     go handle(conn); 
    } 
}