net http详解

http服务器

基本方法

http.HandleFunc-注册回调函数

func HandleFunc(pattern string, handler func(ResponseWriter, *Request))

HandleFunc注册一个处理器函数handler和对应的模式pattern(注册到DefaultServeMux)。ServeMux的文档解释了模式的匹配机制。

http.ListenAndServe-监听

func ListenAndServe(addr string, handler Handler) error

ListenAndServe监听TCP地址addr,并且会使用handler参数调用Serve函数处理接收到的连接。handler参数一般会设为nil,此时会使用DefaultServeMux。

实例

package main

import (
	"fmt"
	"net/http"
)

func main(){
	//注册回调函数
	http.HandleFunc("/hello", handler)

	//绑定tcp监听地址,并开始接受请求,然后调用服务端处理程序来处理传入的连接请求。
	//params:第一个参数 addr 即监听地址;第二个参数表示服务端处理程序,通常为nil
	//当参2为nil时,服务端调用 http.DefaultServeMux 进行处理
	http.ListenAndServe("127.0.0.1:8080", nil)
}

func handler (w http.ResponseWriter, r *http.Request){
	fmt.Println("method = ", r.Method) 	//请求方法
	fmt.Println("URL = ", r.URL)		// 浏览器发送请求文件路径
	fmt.Println("header = ", r.Header)	// 请求头
	fmt.Println("body = ", r.Body)		// 请求包体
	fmt.Println(r.RemoteAddr, "连接成功")  	//客户端网络地址

	w.Write([]byte("hello http server"))
}

http客户端

基本方法

func (c *Client) Get(url string) (r *Response, err error) 
func (c *Client) Post(url string, bodyType string, body io.Reader) (r *Response, err 
 error) 
func (c *Client) PostForm(url string, data url.Values) (r *Response, err error) 
func (c *Client) Head(url string) (r *Response, err error) 
func (c *Client) Do(req *Request) (resp *Response, err error)

实例

package main

import(
    "fmt"
    "net/http"
)

func main(){
   // 使用Get方法获取服务器响应包数据
   resp, err := http.Get("http://127.0.0.1:8080/hello")
   if err != nil {
      fmt.Println("Get err:", err)
      return
   }
   defer resp.Body.Close()

   // 获取服务器端读到的数据
   fmt.Println("Status = ", resp.Status)           // 状态
   fmt.Println("StatusCode = ", resp.StatusCode)   // 状态码
   fmt.Println("Header = ", resp.Header)           // 响应头部
   fmt.Println("Body = ", resp.Body)               // 响应包体

   //读取body内的内容
    content, err := ioutil.ReadAll(resp.Body)
   
   // 打印从body中读到的所有内容
    fmt.Println("result = ", string(content))

}

post上传文件

根据文件路径上传文件

package main

import (
    "fmt"
    "io"
    "net/http"
    "log"
)

// 获取大小的借口
type Sizer interface {
    Size() int64
}

// hello world, the web server
func HelloServer(w http.ResponseWriter, r *http.Request) {
    if "POST" == r.Method {
    file, _, err := r.FormFile("userfile")
    if err != nil {
        http.Error(w, err.Error(), 500)
        return
    }
    defer file.Close()
    f,err:=os.Create("filenametosaveas")
    defer f.Close()
    io.Copy(f,file)
fmt.Fprintf(w, "上传文件的大小为: %d", file.(Sizer).Size())
    return
    }

    // 上传页面
    w.Header().Add("Content-Type", "text/html")
    w.WriteHeader(200)
    html := `
<form enctype="multipart/form-data" action="/hello" method="POST">
    Send this file: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>
`
    io.WriteString(w, html)
}

func main() {
    http.HandleFunc("/hello", HelloServer)
    err := http.ListenAndServe(":12345", nil)
    if err != nil {
    log.Fatal("ListenAndServe: ", err)
    }
}

客户端上传文件代码:
 func Upload() (err error) {
    // Create buffer
    buf := new(bytes.Buffer) // caveat IMO dont use this for large files, \
    // create a tmpfile and assemble your multipart from there (not tested)
    w := multipart.NewWriter(buf)
    // Create file field
    fw, err := w.CreateFormFile("file", "helloworld.go") //这里的file很重要,必须和服务器端的FormFile一致
    if err != nil {
    fmt.Println("c")
    return err
    }
    fd, err := os.Open("helloworld.go")
    if err != nil {
    fmt.Println("d")
    return err
    }
    defer fd.Close()
    // Write file field from file to upload
    _, err = io.Copy(fw, fd)
    if err != nil {
    fmt.Println("e")
    return err
    }
    // Important if you do not close the multipart writer you will not have a
    // terminating boundry
    w.Close()
    req, err := http.NewRequest("POST","http://192.168.2.127/configure.go?portId=2", buf)
    if err != nil {
    fmt.Println("f")
    return err
    }
    req.Header.Set("Content-Type", w.FormDataContentType())
      var client http.Client
    res, err := client.Do(req)
    if err != nil {
    fmt.Println("g")
    return err
    }
    io.Copy(os.Stderr, res.Body) // Replace this with Status.Code check
    fmt.Println("h")
    return err
}

如果穿进来的是已经打开的文件的文件流上传方法

func (dfs *fastdfsUploader) PutImage(data []byte) (string, error) {
	buf := new(bytes.Buffer)
	writer := multipart.NewWriter(buf)
	
	//这个函数的作用是生成一个文件名,不必关注,直接携程image_name= xzw.jpg都行
	image_name := generateImageKey(data)
	fw, err := writer.CreateFormFile("file", image_name) //这里的file很重要,必须和服务器端的FormFile一致
	if err != nil {
		logs.LogInstance().Error("create form error %s",err.Error())
		return "",err
	}
	_, err = io.Copy(fw, bytes.NewReader(data))
	if err != nil {
		logs.LogInstance().Error("io copy error %s",err.Error())
		return "",err
	}
	writer.Close()

	_host := config.Conf.UploaderFastdfs.Host



	client := &http.Client{}
	req, err := http.NewRequest("POST", _host+"/upload?scene=image&output=json",buf)
	if err != nil {
		// handle error
		logs.LogInstance().Error("create request post error!")
		return "",errors.New("create request post error!")
	}



	req.Header.Set("Content-Type",writer.FormDataContentType())
	resp, err := client.Do(req)
	if err != nil {
		logs.LogInstance().Error("client do error %s",err.Error())
		return "",err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		// handle error
		logs.LogInstance().Error("get post result error!")
		return "",errors.New("get post result error!")
	}

	logs.LogInstance().Info(string(body))
	logs.LogInstance().Info("data len :%d buf len: %d", len(data),buf.Len())

	return string(body),nil
}

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×