使用Golang构建服务器但在客户端有问题

时间:2014-09-03 09:29:23

标签: web go webserver

这是我的代码:

package main

import (
        "fmt"
        "net"
        "net/http"
        "os"
)

const RECV_BUF_LEN = 1024

func handler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprint(w, "Test")
}

func main() {
        http.HandleFunc("/", handler)
        s := &http.Server{Addr: ":8080", Handler: nil}
        listener, err := net.Listen("tcp", s.Addr)
        if err != nil {
                fmt.Println("Error: ", err.Error())
                fmt.Println("Close Server")
                os.Exit(1)
        }

        for {
                conn, err := l.Accept()
                if err != nil {
                        fmt.Println("Error: ", err.Error())
                        continue
                }
                go ClientLogic(conn)
        }
}

func ClientLogic(conn net.Conn) {
        fmt.Println("Connect Successful")
        conn.Close()
}

我知道我可以使用以下代码来构建服务器,但我想做一些事情,比如打印一些数据。

http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)

当代码运行时,服务器端可以打印" Connect Successful"成功。

然而,它并没有在客户端显示任何内容。

换句话说,客户端的浏览器显示任何内容并继续加载,但服务器端可以显示有关成功连接的消息。

PS:代码引用http://lolikitty.pixnet.net/blog/post/148420590和golang的源代码(http://golang.org/src/pkg/net/http/server.go?s=50405:50451#L1684

3 个答案:

答案 0 :(得分:2)

我不确定您要尝试实现的目标,但该代码存在一些重大问题。

  1. http.HandleFunc("/", handler)DefaultServeMux.HandleFunc(pattern, handler)的别名,但由于您的代码无论如何都不涉及DefaultServeMux甚至http.Server,因此它是&#39}。没用了。

  2. (并非真正相关但是)你从Accept()检查错误然后继续,但是来自接受的任何错误都是致命的,你无法在大多数时间内从中恢复。 / p>

  3. func ClientLogic(conn net.Conn)立即关闭连接而不对其做任何事情,您期望发生什么?

  4. 如果你想要的只是出于某种原因访问原始连接,你总是可以实现像this这样的东西:

    http.HandleFunc("/hijack", func(w http.ResponseWriter, r *http.Request) {
        hj, ok := w.(http.Hijacker)
        if !ok {
            http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
            return
        }
        conn, bufrw, err := hj.Hijack()
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        // Don't forget to close the connection:
        defer conn.Close()
        bufrw.WriteString("Now we're speaking raw TCP. Say hi: ")
        bufrw.Flush()
        s, err := bufrw.ReadString('\n')
        if err != nil {
            log.Printf("error reading string: %v", err)
            return
        }
        fmt.Fprintf(bufrw, "You said: %q\nBye.\n", s)
        bufrw.Flush()
    })
    http.ListenAndServe(":8080", nil)
    

答案 1 :(得分:0)

您应该使用处理程序或接受,但如果您使用accept,则将处理新连接并忽略处理程序。您将进入http连接的较低抽象级别。

这段代码按预期工作:

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Test")
    fmt.Println("Connect Successful")
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

当您致电ListenAndServe时,他会做出正确的接受,因此您无需担心。

答案 2 :(得分:0)

  

OneOfOne:

     
    

我不确定您要尝试实现的目标,但该代码存在一些重大问题。

         

1)http.HandleFunc("/", handler)DefaultServeMux.HandleFunc(pattern, handler)的别名,但由于您的代码无论如何都不涉及DefaultServeMux甚至http.Server,因此它无用。

         

3)func ClientLogic(conn net.Conn)立即关闭连接而不对其做任何事情,你期望发生什么?

  

1)在golang的软件包中,它表示DefaultServeMux是处理程序的默认值。因此,我从不关心它。

3)http://lolikitty.pixnet.net/blog/post/148420590中的代码可以显示如下数据:

接收  409  個 byte 資料: GET / HTTP/1.1 
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110422 Ubuntu/9.10 (karmic) Firefox/3.6.17
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cache-Control: max-age=0

我想要做的是我的服务器可以显示这些信息。

  

mcuadros:

     
    

您应该使用处理程序或接受,但如果您使用接受,则将处理新连接并忽略处理程序。您将进入http连接的较低抽象级别。

         

当你打电话给ListenAndServe时,他会做出正确的接受,所以你不用担心。

  

感谢您的代码,它可以做我想要的。

我想确定一下。我的代码问题是我使用listener.Accept()建立新连接。因此我的处理程序被忽略。由于新连接,服务器可以显示某些内容。客户端无法显示任何内容,因为它来自旧处理程序,不是吗?