客户端------------请求包--------------->服务器
<---------响应包-----------------
1.http请求包格式
package main
import (
"fmt"
"net"
)
func main() {
//监听,指明协议类型,ip地址,端口号,“:8000”=“127.0.0.1:8000”
listener, err := net.Listen("tcp", ":8000")
if err != nil {
fmt.Println("net.Listen err=", err)
return
}
defer listener.Close()
//阻塞等待用户连接
conn, err1 := listener.Accept()
if err1 != nil {
fmt.Println("listener.Accept err=", err1)
return
}
defer conn.Close()
buf := make([]byte, 1024*4)//新建缓冲区,存储从客户端来的请求包
n, err2 := conn.Read(buf)
if n == 0 {
fmt.Println("conn.Read err=", err2)
return
}
fmt.Printf("#%v#", string(buf[:n]))
}
2.响应包格式
//测试服务器
package main
import (
"fmt"
"net/http"
)
func myHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello world")
}
func main() {
http.HandleFunc("/go", myHandler)
http.ListenAndServe("127.0.0.1:8000", nil)
}
package main
import (
"fmt"
"net"
)
func main() {
//主动连接服务器
conn, err := net.Dial("tcp", ":8000")
if err != nil {
fmt.Println("net.Dial err=", err)
return
}
defer conn.Close()
//这是一个请求包
requestBuf := "GET /go HTTP/1.1\r\nAccept: image/gif, imagejpeg, image/pjpeg,application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*\r\nAccept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.3\r\nUser-Agent: Mozilla/4.0 (compatible;MSIE 7.0; Windows NT 10.0;WOW64;Trident/7.0; .NET4.0C; NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)\r\nAccept-Encoding:gzip, doflate\r\nHost:127.0.0.1:8000\r\nConnection: Keep-Alive\r\n\r\n"
//只有先发请求包,服务器才会发响应包
conn.Write([]byte(requestBuf))
buf := make([]byte, 4*1024)
//接收服务器发来的响应包
n, err1 := conn.Read(buf)
if n == 0 {
fmt.Println("conn.Read err=", err1)
return
}
fmt.Printf("#%v#", string(buf[:n]))//显示响应包的报文
}
连接成功:
连接失败:
状态码及其含义:
状态码 | 含义 |
1xx | 表示服务器已接收了客户端请求,客户端可继续发送请求 |
2xx | 表示服务器已成功接收到请求并进行处理 |
3xx | 表示服务器要求客户端重定向 |
4xx | 表示客户端的请求有非法内容 |
5xx | 表示服务器能正常处理客户端的请求而出现意外错误 |
常用状态码及其含义:
状态码 | 含义 |
200 OK | 客户端请求成功 |
400 Bad Request | 请求报文有语法错误 |
401 Unauthorized | 未授权 |
403 Forbidden | 服务器拒绝服务 |
404 Not Found | 请求的资源不存在 |
500 Internal Server Error | 服务器内部错误 |
503 Server Unavailable | 服务器临时不能处理客户端请求(稍后可能可以) |
3.http服务器
package main
import (
"fmt"
"net/http"
)
//w,给客户端回复数据;req,读取客户端发的数据
func HandleConn(w http.ResponseWriter, req *http.Request) {
fmt.Println("req.Method=", req.Method)
fmt.Println("req.URL=", req.URL)
fmt.Println("req.Header=", req.Header)
fmt.Println("req.Body=", req.Body)
w.Write([]byte("hello go"))//向客户端发送
}
func main() {
//注册处理函数,只要用户连接,就会自动调用指定的处理函数
http.HandleFunc("/", HandleConn)
//监听绑定
http.ListenAndServe(":8000", nil)
}
4.http客户端
package main
import (
"fmt"
"net/http"
)
func main() {
//接收来自服务器的响应包(连接到服务器时,自动发送了请求包)
resp, err := http.Get("http://127.0.0.1:8000")
if err != nil {
fmt.Println("http.Get err=", err)
return
}
defer resp.Body.Close()
fmt.Println("resp.Status=", resp.Status)
fmt.Println("resp.StatusCode=", resp.StatusCode)
fmt.Println("resp.Header=", resp.Header)
buf := make([]byte, 4*1024)
var tmp string
for {
n, err := resp.Body.Read(buf)
if n == 0 {
fmt.Println("resp.Body.Read err=", err)
break
}
tmp += string(buf[:n])
}
fmt.Println("tmp=", tmp)
}