Golang http Programación

flujos de trabajo web

  • servidor Web Works se puede resumir como simplemente
    • Cliente establece con el servidor a través de la conexión del protocolo TCP TCP / IP
    • El cliente envía a la petición de protocolo de paquetes HTTP del servidor, los recursos del servidor que solicitan en el documento
    • El servidor envía el paquete de respuesta al protocolo HTTP cliente, si el recurso solicitado contiene contenido lenguaje dinámico, el servidor llama manejará el motor de interpretación de "contenido dinámico" lenguajes dinámicos, y el procesamiento de la parte posterior de datos resultante al cliente
    • Cliente y el servidor se desconecta. Por el cliente interpreta el documento HTML, el resultado de la representación de gráficos en la pantalla del cliente

protocolo HTTP

  • Protocolo de transferencia de hipertexto (HTTP, Hypertext Transfer Protocol) es un protocolo de red más utilizado en Internet, que detalla las reglas de la comunicación mutua entre el navegador y el servidor Web, el protocolo de transferencia de documentos del World Wide Web para la transferencia de datos a través de Internet
  • protocolo HTTP a través del protocolo TCP normalmente se lleva

HTTP Server

package main

import (
    "fmt"
    "net/http"
)

// /go handler
func goHandler(w http.ResponseWriter, r *http.Request) {
    // 获取远程地址
    fmt.Println(r.RemoteAddr, "连接成功")
    // 获取请求类型
    fmt.Println("请求方法: ", r.Method)
    // 获取url路径
    fmt.Println("url path: ", r.URL.Path)
    // 获取header数据
    fmt.Println("header: ", r.Header)
    // 获取请求body内容
    fmt.Println("body: ", r.Body)

    // 返回信息
    _, _ = w.Write([]byte("hello world"))
}

func main()  {
    // 单独写回掉函数
    http.HandleFunc("/go", goHandler)

    // 启动http监听
    _ = http.ListenAndServe("127.0.0.1:8000", nil)
}

http paquete de cliente

package main

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

func main() {
    resp, err := http.Get("http://127.0.0.1:8000/go")
    if err != nil {
        fmt.Println("获取数据失败, err: ", err)
        return
    }
    defer resp.Body.Close()
    // 获取http状态码
    fmt.Println("status: ", resp.Status)
    // 获取header信息
    fmt.Println("header: ", resp.Status)

    buf := make([]byte, 124)
    for {
        // 接收服务端数据
        n, err := resp.Body.Read(buf)

        fmt.Println(string(buf[:n]))

        if err == io.EOF {
            break
        }

        if err != nil {
            fmt.Println("数据读取失败, err: ", err)
            continue
        }
    }
}

implementos de paquetes TCP del cliente

package main

import (
    "fmt"
    "io"
    "net"
)

func main() {
    conn, err := net.Dial("tcp", "127.0.0.1:8000")
    if err != nil {
        fmt.Println("connect err: ", err)
        return
    }
    defer conn.Close()
    msg := "GET /go HTTP/1.1\r\n"
    msg += "Host: 127.0.0.1:8000\r\n"
    msg += "Connection: close\r\n"
    msg += "\r\n\r\n"

    _, err = io.WriteString(conn, msg)
    if err != nil {
        fmt.Println("write string failed, ", err)
        return
    }
    buf := make([]byte, 4096)
    for {
        n, err := conn.Read(buf)
        if err == io.EOF {
            break
        }
        if err != nil {
            fmt.Println("recv data has err, ", err)
            break
        }
        fmt.Println(string(buf[:n]))
    }
}

otro error

golang GET 出现 x509: certificado firmado por una autoridad desconocida

Nos ir a escribir un programa para tratar de establecer una conexión y comunicación con el servidor HTTPS.

//gohttps/4-https/client1.go
package main

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

func main() {
    resp, err := http.Get("https://localhost:8081")
    if err != nil {
        fmt.Println("error:", err)
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

Ejecutar este cliente, obtenemos el siguiente error:

$go run client1.go
error: Get https://localhost:8081: x509: certificate signed by unknown authority

En este punto el registro de errores de servidor también da consejos:

2015/04/30 16:03:31 http: TLS handshake error from 127.0.0.1:62004: remote error: bad certificate

Obviamente, desde el punto de vista de cliente del registro, vaya a darse cuenta del valor por defecto es cliente-servidor para pasar sobre la verificación del certificado digital, pero el cliente Nota: Este certificado es emitido por una entidad de certificación de desconocido!

Client1.go podemos modificar el código para que el lado del cliente omitir la comprobación de los certificados:

//gohttps/4-https/client2.go
package main

import (
"crypto/tls"
"fmt"
"io/ioutil"
"net/http"
)

func main() {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://localhost:8081")

    if err != nil {
        fmt.Println("error:", err)
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))

}

, Certificado de servidor de cliente no va a ser verificada mediante el establecimiento de la verdad InsecureSkipVerify tls.Config. Aplicación de los resultados también confirmó esto:

$go run client2.go
Hi, This is an example of http service in golang!

http conjunto encabezado de la solicitud

package main
import (
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
    "encoding/json"
)

func main() { //生成client 参数为默认
    client := &http.Client{}
    //生成要访问的url
    url := "http://somesite/somepath/"
    //提交请求
    reqest, err := http.NewRequest("GET", url, nil)

    //增加header选项
    reqest.Header.Add("Cookie", "xxxxxx")
    reqest.Header.Add("User-Agent", "xxx")
    reqest.Header.Add("X-Requested-With", "xxxx")

    if err != nil {
        panic(err)
    }
    //处理返回结果
    response, _ := client.Do(reqest)
    defer response.Body.Close()
}

http solicitudes de proxy

package main

import (
    "crypto/tls"
    "fmt"
    "io"
    "net/http"
    "net/url"
    "time"
)

// http proxy get方法
func httpProxyGet(dataUrl, proxyIp string) (data []byte,  err error) {
    transport := &http.Transport{
        TLSClientConfig:   &tls.Config{InsecureSkipVerify: true}, //ssl证书报错问题
        DisableKeepAlives: false,                                 //关闭连接复用,因为后台连接过多最后会造成端口耗尽
        MaxIdleConns:      -1,                                    //最大空闲连接数量
        IdleConnTimeout:   time.Duration(5 * time.Second),        //空闲连接超时时间
        Proxy: http.ProxyURL(&url.URL{
            Scheme: "http",
            Host:   proxyIp,
        }),
    }
    // 设置代理方式二
    //proxyUrl, _ := url.Parse("http://" + proxyIp)
    //transport.Proxy = http.ProxyURL(proxyUrl)

    // 创建http客户端
    client := &http.Client{
        Timeout:   time.Duration(30 * time.Second),
        Transport: transport,
    }

    request, err := http.NewRequest("GET", dataUrl, nil)
    if err != nil {
        return
    }
    // 请求数据
    resp, err := client.Do(request)
    if err != nil {
        err = fmt.Errorf("request %s, proxyIp: (%s),err: %v", dataUrl, proxyIp, err)
        return
    }
    defer resp.Body.Close()
    // 读取数据
    buf := make([]byte, 128)
    data = make([]byte, 0, 2048)
    for {
        n, err := resp.Body.Read(buf)
        data = append(data, buf[:n]...)

        if err == io.EOF {
            break
        }
        if err != nil {
            continue
        }
    }
    return
}


func main() {
    data, err := httpProxyGet("http://www.baidu.com/", "89.22.11.55:9000")
    if err != nil {
        println(err)
        return
    }
    fmt.Println(string(data))
}

Programación WebSocket

¿Cuál es WebSocket

  • protocolo WebSocket es una comunicación dúplex total sobre una única conexión TCP
  • WebSocket permite el intercambio de datos entre el cliente y el servidor más fácil, permitiendo que el servidor al cliente empujar datos de forma activa
  • En la API WebSocket, el navegador y el servidor sólo tiene que completar un apretón de manos, se pueden crear directamente una conexión persistente entre los dos, y la transmisión de datos bidireccional
  • Es necesario instalar paquetes de terceros:
    • cmd en:go get -u -v github.com/gorilla/websocket

ejemplo WebSocket

el servidor

package main

import (
    "github.com/gorilla/websocket"
    "log"
    "net/http"
)

var upgrader = websocket.Upgrader{  // 配置websocker选项
    // 允许websocket跨域
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

func echo(w http.ResponseWriter, r *http.Request) {
    c, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Print("upgrade:", err)
        return
    }
    defer c.Close()
    for {
        mt, message, err := c.ReadMessage()
        if err != nil {
            log.Println("read:", err)
            break
        }
        log.Printf("recv: %s", message)
        err = c.WriteMessage(mt, message)
        if err != nil {
            log.Println("write:", err)
            break
        }
    }
}
func main() {
    log.SetFlags(0)
    http.HandleFunc("/echo", echo)
    log.Fatal(http.ListenAndServe("127.0.0.1:8081", nil))
}

html cliente

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>websocket demo</title>
  </head>
  <body>
    <table>
      <tr>
        <td valign="top" width="50%">
          <p>
            Click "Open" to create a connection to the server, "Send" to send a
            message to the server and "Close" to close the connection. You can
            change the message and send multiple times.
          </p>
          <form>
            <button id="open">Open</button>
            <button id="close">Close</button>
            <input id="input" type="text" value="Hello world!" />
            <button id="send">Send</button>
          </form>
        </td>
        <td valign="top" width="50%">
          <div id="output"></div>
        </td>
      </tr>

      <script>
        window.addEventListener('load', function(evt) {
          var output = document.getElementById('output')
          var input = document.getElementById('input')
          var ws
          var print = function(message) {
            var d = document.createElement('div')
            d.innerHTML = message
            output.appendChild(d)
          }
          document.getElementById('open').onclick = function(evt) {
            if (ws) {
              return false
            }
            ws = new WebSocket('ws://127.0.0.1:8081/echo')
            ws.onopen = function(evt) {
              print('OPEN')
            }
            ws.onclose = function(evt) {
              print('CLOSE')
              ws = null
            }
            ws.onmessage = function(evt) {
              print('RESPONSE: ' + evt.data)
            }
            ws.onerror = function(evt) {
              print('ERROR: ' + evt.data)
            }
            return false
          }
          document.getElementById('send').onclick = function(evt) {
            if (!ws) {
              return false
            }
            print('SEND: ' + input.value)
            ws.send(input.value)
            return false
          }
          document.getElementById('close').onclick = function(evt) {
            if (!ws) {
              return false
            }
            ws.close()
            return false
          }
        })
      </script>
    </table>
  </body>
</html>

Supongo que te gusta

Origin www.cnblogs.com/zhichaoma/p/12509733.html
Recomendado
Clasificación