zoukankan      html  css  js  c++  java
  • Go语言网络编程/Socket、http

    GO语言和网络编程有关的包都在net包下,通过net包及其子包,可以实现各种协议编程、Socket编程、http编程、rpc编程等。

    一、Socket编程

    1、Dial函数

    Go语言中 Dial() 函数用于创建网络连接,函数原型如下:

    func Dial(network, address string) (Conn, error) {   
        var d Dialer 
        return d.Dial(network, address)
    }
    

    参数说明如下:

    • network 参数表示传入的网络协议(比如 tcp、udp 等);
    • address 参数表示传入的 IP 地址或域名,而端口号是可选的,如果需要指定的话,以:的形式跟在地址或域名的后面即可。如果连接成功,该函数返回连接对象,否则返回 error。

    实际上,Dial() 函数是对 DialTCP()、DialUDP()、DialIP()、DialUnix() 函数的封装:

    func DialTCP(net string, laddr, raddr *TCPAddr) (c *TCPConn, err error)
    func DialUDP(net string, laddr, raddr *UDPAddr) (c *UDPConn, err error)
    func DialIP(netProto string, laddr, raddr *IPAddr) (c *IPConn, err error)
    func DialUnix(net string, laddr, raddr *UnixAddr) (c *UnixConn, err error)
    

    在成功建立连接后,我们就可以进行数据的发送和接收,发送数据时使用连接对象 conn 的 Write() 方法,接收数据时使用 Read() 方法。

    2、Listen函数

    net包下个Listen函数会监听一个地址,返回一个监听器对象。

    func Listen(network, address string) (Listener, error) {  
        var lc ListenConfig   
        return lc.Listen(context.Background(), network, address)
    }
    

    3、Socket客户端/服务端

    通过net包下的Dial和Listen函数来实现一个Socket编程。

    服务器端:

    通过Listen函数监听端口,接收来自客户端的请求。

    监听器的Accept()方法是阻塞的,接收不到消息就会一直等待。

    使用for循坏持续监听,并发处理接收的请求。

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"net"
    	"os"
    )
    
    func main() {
    
    	listener, _ := net.Listen("tcp", ":8888")
    
    	fmt.Println("开始监听...")
    
    	for{
    		conn, err := listener.Accept()//接收客户端发来的请求
    		if err!=nil{
    			fmt.Fprintln(os.Stdout,"错误:",err)
    		}
    		go handler(conn)//并发处理
    		
    	}
    
    	defer listener.Close()//关闭监听器
    }
    
    func handler(conn net.Conn)  {//处理器
    
    	defer  conn.Close()
    	conn.Write([]byte("已经收到..."))//响应客户端的数据
    
    	reader := bufio.NewReader(conn)
    
    	s, _ := reader.ReadString('
    ')
    
    	fmt.Fprintln(os.Stdout,s)//将客户端发送的数据输出
    
    }
    
    

    客户端:

    package main
    
    import (
    	"fmt"
    	"net"
    )
    
    func main() {
    
    	conn, _ := net.Dial("tcp", "127.0.0.1:8888")//建立Tcp连接
    
    	defer  conn.Close()//关闭连接
    
    	conn.Write([]byte("hello world"))//发出数据
    
    
    
    	bytes := make([]byte, 100)
    	n, _ := conn.Read(bytes)//读取数据
    
    	fmt.Println(string(bytes[0:n]))
    
    }
    
    

    二、Http编程

    http包提供了HTTP客户端和服务端的实现。

    Get、Head、Post和PostForm函数发出HTTP/ HTTPS请求。

    1、request

    测试:

    使用Get方法向测试网站发送一个请求。

    package main
    
    import (
    	"io"
    	"net/http"
    	"os"
    )
    
    func main() {
        //使用Get请求获得一个
    	resp, _ := http.Get("http://jsonplaceholder.typicode.com/users")
    
    	l:=resp.Body//响应体
    
    	io.Copy(os.Stdout, l)//将响应体数据输出
        //Fprint系函数按照默认格式输出、在此不适用
        
        
        request := resp.Request//获取请求
        
        
        fmt.Println("Header    ",request.Header)
    	fmt.Println("Body    ",request.Body)
    	fmt.Println("Method    ",request.Method)
    
    	defer l.Close()
    
    }
    
    

    2、web服务

    http包中还提供了web服务。

    使用非常简单,只需要两步就可以启动一个简单的服务器:

    1、设置一个入口处理器

    使用http.HandleFunc()或者http.Handle()函数设置入口。

    2、监听端口并启动服务

    http.ListenAndServe()用于监听并启动服务。

    package main
    
    import (
    	"fmt"
    	"net/http"
    )
    
    func main() {
    	
        //处理器设置,第一个为入口url,第二个为处理器函数名
    	http.HandleFunc("/hello",hand)
    
        //监听地址,第二个参数为Handler,nil代表不使用Handler
    	http.ListenAndServe(":8888",nil)
    }
    
    
    //处理器函数,必须接受w http.ResponseWriter, r *http.Request作为参数
    func hand(w http.ResponseWriter, r *http.Request)  {
    
    	fmt.Fprintln(w,"<h1>Hello Web</h1>")//将数据发送给响应写入
    }
    

    此时运行服务,访问浏览器 localhost:8888/hello,出现以下内容:

    Hello Web
    

    3、模板引擎

    go标准库中自带了模板引擎。

    所谓模板引擎就是某些文本可以重复使用,只有部分数据需要变更,能够将需要变更的部分数据用特定的语法代替,用于被实际数据注入的一种机制。

    如下:{{data}}中的data可以从外界注入,外界注入什么数据就会输出hello 什么。

    <body>
        <h1>hello  {{data}}</h1>
    </body>
    
    

    template包(html/template)实现了数据驱动的模板,用于生成可对抗代码注入的安全HTML输出。

    go中的模本语法如下:

    {{.}}
    使用{{}}圈住数据,.代表注入的数据。
    如果注入的是结构体或者map,通过字段名字和key表示.
    
    {{.Name}}拿到注入结构体的Name字段,如果字段不可见,即字段名小写,此时无法拿到数据
    {{.k1}}拿到植入map的key为k1的value
    
    

    测试:

    import (
    	"html/template"
    	"os"
    )
    
    const tpl  ="hello world ,hello {{.}}"//模板字段
    
    func main() {
    
        //给模板起个名字并解析tpl字段
    	parse, _ := template.New("tpl_1").Parse(tpl)
    
        //开始解析,参数一是将解析后的数据输出、参数二是注入的数据
    	parse.Execute(os.Stdout,"杰米")
    
    }
    
    //此时控制台:
    hello world ,hello 杰米
    
    

    模板引擎也常用于web中,用于对html的解析。

    package main
    
    import (
    	"fmt"
    	"html/template"
    	"net/http"
    )
    
    func main() {
    
    	http.HandleFunc("/hello",hand)
    
    	http.ListenAndServe(":8888",nil)
    }
    
    func hand(w http.ResponseWriter, r *http.Request)  {
    
    
    
    	fmt.Fprintln(w,"<h1>Hello Web</h1>")
    
        //从文件中解析
    	files, err:= template.ParseFiles("you url/hello.html")
    
    	if err!=nil{
    		fmt.Println(err)
    	}
        //写入响应中
    	files.Execute(w,"jim")
    
    
    }
    
    
  • 相关阅读:
    Nginx编译安装第三方模块http_substitutions_filter_module
    房产网站网址收藏
    nginx图片过滤处理模块http_image_filter_module安装配置笔记
    Lua顺序 执行顺序
    Dig HOWTO 中文手册--dig命令使用大全
    没有局域网环境,全是公网IP可以做LVS吗,该如何做了!请大家赐教!
    Nginx HttpSubModule sub_filter模块的过滤功能
    NGINX扩展
    oracle中导出sql的几个常见词语的意思
    int型变量,不使用中间变量完成互换
  • 原文地址:https://www.cnblogs.com/cgl-dong/p/14035072.html
Copyright © 2011-2022 走看看