Reputation: 121
This is my code:
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()
}
I know I can use following code to build a server but I want do some stuffs, such as printing some datas.
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
When the code run, the server-side can print "Connect Successful" successfully.
However, the it doesn't display anything in client-side.
In other words, the client's browser display anything and keep loading but the server-side can display the message about connecting successfully.
PS: The code refer to http://lolikitty.pixnet.net/blog/post/148420590 and the golang's source code ( http://golang.org/src/pkg/net/http/server.go?s=50405:50451#L1684 )
Upvotes: 0
Views: 1366
Reputation: 121
OneOfOne:
I'm not sure what you're trying to achieve but there are some major problems with that code.
1)
http.HandleFunc("/", handler)
is an alias forDefaultServeMux.HandleFunc(pattern, handler)
, but since your code doesn't involve DefaultServeMux in anyway or even http.Server, it's useless.3)
func ClientLogic(conn net.Conn)
closes the connection immediately without doing anything to it, whatdid you expect to happen?
1) in golang's package, it says the DefaultServeMux
is the default value of handler. Therefore I never care about it.
3) The code in http://lolikitty.pixnet.net/blog/post/148420590 can display the data like following:
接收 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
What I want to do is that my server can display those information.
mcuadros:
You should use the handler or the accept, but if you use the accept this will be handled the new connection and you are ignoring the handler. You are going to a lower abstraction level of the http connection.
When you call to ListenAndServe, he make the correct Accept so you dont need to worry about.
Thanks for your code, it can do what I want.
I want to make sure. The issue of my code is I use listener.Accept()
to make a new connection. Therefore my handler is ignored. The server can display something because of the new connection. The client side cannot display anything because it is from the old handler, doesn't it?
Upvotes: 0
Reputation: 99224
I'm not sure what you're trying to achieve but there are some major problems with that code.
http.HandleFunc("/", handler)
is an alias for DefaultServeMux.HandleFunc(pattern, handler)
, but since your code doesn't involve DefaultServeMux
in anyway or even http.Server
, it's useless.
(not really related but) you check for errors from Accept()
then continue, but any error from accept is fatal pretty much and you can't recover from it most of the time.
func ClientLogic(conn net.Conn)
closes the connection immediately without doing anything to it, what did you expect to happen?
If all you want is access to the raw connection for some reason you can always implement something like 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)
Upvotes: 2
Reputation: 4144
You should use the handler or the accept, but if you use the accept this will be handled the new connection and you are ignoring the handler. You are going to a lower abstraction level of the http connection.
This piece of code work as you expect:
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)
}
When you call to ListenAndServe, he make the correct Accept so you dont need to worry about.
Upvotes: 0