• golang 的net包的网络编程 TCP | HTTP | RPC Marathon



    golang net包

    1.TCP网络编程

    server.go

    package main
    
    import (
    	"fmt"
    	"log"
    	"net"
    	"os"
    	"time"
    )
    
    func main()  {
    	// 建立socket监听
    	lis, err := net.Listen("tcp", "localhost:1024")
    	log.Println("server up at " + lis.Addr().String())
    	defer lis.Close()
    	log.Println("Waiting for clients...")
    
    	// 处理错误
    	if err != nil {
    		fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
    	}
    
    	// 处理客户端连接
    	for {
    		conn, err := lis.Accept()
    		if err != nil {
    			continue
    		}
    
    		log.Printf("client addr: %s, tcp connect success", conn.RemoteAddr())
    		go handle(conn)
    	}
    }
    
    func handle(conn net.Conn)  {
    	buffer := make([]byte, 2048)
    	// 循环读取客户请求
    	for {
    		n, err := conn.Read(buffer)
    		if err != nil {
    			log.Printf("%s connection error: %s", conn.RemoteAddr(), err)
    			return
    		}
    		log.Printf("From %s receive data string: %s\n", conn.RemoteAddr(), string(buffer[:n]))
    		// 收到的返回信息
    		strTmp := fmt.Sprintf("server got msg \"%s\" at %s", string(buffer[:n]), time.Now().String())
    		conn.Write([]byte(strTmp))
    	}
    }
    

    client.go

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"log"
    	"net"
    	"os"
    )
    
    func main()  {
    	addr := "127.0.0.1:1024"
    	conn, err := net.Dial("tcp", addr)
    	defer conn.Close()
    	if err != nil {
    		fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
    		os.Exit(1)
    	}
    
    	log.Printf("connection server: %s success", addr)
    	sendLoop(conn)
    }
    
    func send(conn net.Conn)  {
    	words := "hello server!"
    	conn.Write([]byte(words))
    	log.Println("send over")
    
    	// receive from server
    	buffer := make([]byte, 2048)
    
    	n, err := conn.Read(buffer)
    	if err != nil {
    		log.Printf("%s waiting server back msg error: %s", conn.RemoteAddr(), err)
    		return
    	}
    	log.Printf("%s receive server back msg: %s", conn.RemoteAddr(), string(buffer[:n]))
    }
    
    func sendLoop(conn net.Conn)  {
    	for {
    		input, _ := bufio.NewReader(os.Stdin).ReadString('\n')
    		_, err := conn.Write([]byte(input))
    		if err != nil {
    			log.Println(err)
    		}
    		log.Println("send over")
    
    		// receive from server
    		buffer := make([]byte, 2048)
    
    		n, err := conn.Read(buffer)
    		if err != nil {
    			log.Printf("%s waiting server back msg error: %s", conn.RemoteAddr(), err)
    			return
    		}
    		log.Printf("%s receive server back msg: %s", conn.RemoteAddr(), string(buffer[:n]))
    	}
    
    }
    
    

    2.HTTP网络编程

    2.1 HTTP

    server.go

    package main
    
    import (
    	"fmt"
    	"log"
    	"net/http"
    )
    
    func main()  {
    	// register callback func
    	http.HandleFunc("/index", indexHandle)
    	log.Println("HTTP server up at", "http://localhost:8080")
    	// bind ip and start recv req
    	err := http.ListenAndServe(":8080", nil)
    	if err != nil {
    		log.Fatal("ListenAndServe:", err)
    	}
    }
    
    func indexHandle(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 from http server"))
    	//fmt.Fprint(w, "Hello from http server")
    }
    
    

    client.go

    package main
    
    import (
    	"fmt"
    	"io/ioutil"
    	"log"
    	"net/http"
    )
    
    func main()  {
    	resp, err := http.Get("http://localhost:8080/index")
    	if err != nil {
    		log.Println("Get err:", err)
    		return
    	}
    	defer resp.Body.Close()
    
    	// parse resp data
    	// 获取服务器端读到的数据---header
    	fmt.Println("Status = ", resp.Status)           // 状态
    	fmt.Println("StatusCode = ", resp.StatusCode)   // 状态码
    	fmt.Println("Header = ", resp.Header)           // 响应头部
    	fmt.Println("Body = ", resp.Body)               // 响应包体
    	// resp body
    	content, err := ioutil.ReadAll(resp.Body)
    	log.Println("response body:", string(content))
    }
    
    

    2.2 HTTPS

    server.go

    package main
    
    import (
    	"fmt"
    	"log"
    	"net/http"
    )
    
    func main()  {
    	http.HandleFunc("/index", indexHandle)
    
    	log.Println("HTTPS server up at https://localhost:8443")
    	http.ListenAndServeTLS(":8443", "D:\\demo1\\src\\demo\\demo05\\https-server\\server\\server.crt",
    		"D:\\demo1\\src\\demo\\demo05\\https-server\\server\\server.key", nil)
    }
    
    func indexHandle(w http.ResponseWriter, r *http.Request)  {
    	log.Println(r.RemoteAddr, r.URL, r.Proto, r.Header, r.Body)
    	fmt.Fprint(w, "Hi, This is an example of https service in golang!")
    }
    
    

    client.go

    package main
    
    import (
    	"crypto/tls"
    	"crypto/x509"
    	"io/ioutil"
    	"log"
    	"net/http"
    )
    
    func main()  {
    	// create cert pool, which stands for cert set
    	pool := x509.NewCertPool()
    	caCrtPath := "D:\\demo1\\src\\demo\\demo05\\https-server\\client\\ca.crt"
    	// call ca.crt
    	caCrt, err := ioutil.ReadFile(caCrtPath)
    	if err != nil {
    		log.Println("ReadFile err:", err)
    		return
    	}
    
    	// parse cert
    	pool.AppendCertsFromPEM(caCrt)
    	tr := &http.Transport{
    		// InsecureSkipVerify-如果设置为true, 则不会校验证书以及证书中的主机名和服务器主机名是否一致
    		TLSClientConfig: &tls.Config{RootCAs: pool, InsecureSkipVerify: true},
    	}
    
    	client := &http.Client{Transport: tr}
    
    	resp, err := client.Get("https://localhost:8443/index")
    	if err != nil {
    		log.Println("Get err:", err)
    		return
    	}
    	defer resp.Body.Close()
    	content, err := ioutil.ReadAll(resp.Body)
    	log.Println(string(content))
    }
    

    3.RPC网络编程

    参考:net/rpc——Server/Client之间通信的秘密

    3.1 基于TCP的RPC

    server.go

    
    

    client.go

    
    

    3.2 基于HTTP的RPC

    server.go

    package main
    
    import (
    	"fmt"
    	"log"
    	"net/http"
    	"net/rpc"
    )
    
    type Student struct {
    	Name   string
    	School string
    }
    
    type RpcServer struct {}
    
    func (r *RpcServer) Introduce(student Student, words *string) error {
    	log.Println("student:", student)
    	*words = fmt.Sprintf("Hello everyone, my name is %s, and I am from %s", student.Name, student.School)
    	return nil
    }
    
    func main()  {
    	rpcServer := new(RpcServer)
    	// register rpc service
    	_ = rpc.Register(rpcServer)
    	// service bind to http protocol
    	rpc.HandleHTTP()
    	log.Println("http rpc service start success addr:8080")
    	err := http.ListenAndServe(":8080", nil)
    	if err != nil {
    		log.Fatal(err)
    	}
    }
    
    

    client.go

    package main
    
    import (
    	"log"
    	"net/rpc"
    )
    
    func main()  {
    	type Student struct {
    		Name   string
    		School string
    	}
    	// connect rpc server
    	client, err := rpc.DialHTTP("tcp", "127.0.0.1:8080")
    	if err != nil {
    		panic(err)
    	}
    	defer client.Close()
    	// send request
    	var reply string
    	err = client.Call("RpcServer.Introduce", &Student{Name: "random_w", School: "Secret"}, &reply)
    	if err != nil {
    		panic(nil)
    	}
    	log.Println(reply)
    }
    
    

    3.3 基于jsonRpc的RPC

    server.go

    package main
    
    import (
    	"fmt"
    	"log"
    	"net"
    	"net/rpc"
    	"net/rpc/jsonrpc"
    )
    
    type Student struct {
    	Name   string
    	School string
    }
    
    type RpcServer struct{}
    
    func (r *RpcServer) Introduce(student Student, words *string) error {
    	log.Println("student: ", student)
    	*words = fmt.Sprintf("Hello everyone, my name is %s, and I am from %s", student.Name, student.School)
    	return nil
    }
    
    func main()  {
    	rpcServer := new(RpcServer)
    	// register rpc service
    	_ = rpc.Register(rpcServer)
    	// json-rpc based on tcp protocol, not http
    	tcpLis, err := net.Listen("tcp", "127.0.0.1:8080")
    	if err != nil {
    		panic(err)
    	}
    
    	log.Println("tcp json-rpc service start success addr:8080")
    	for {
    		// listen request from clients
    		conn, err := tcpLis.Accept()
    		if err != nil {
    			continue
    		}
    		go jsonrpc.ServeConn(conn)
    	}
    }
    

    client.go

    package main
    
    import (
    	"log"
    	"net/rpc/jsonrpc"
    )
    
    func main()  {
    	type Student struct {
    		Name string
    		School string
    	}
    
    	client, err := jsonrpc.Dial("tcp", "127.0.0.1:8080")
    	if err != nil {
    		panic(err)
    	}
    	defer client.Close()
    	var reply string
    	err = client.Call("RpcServer.Introduce", &Student{
    		Name: "random_w",
    		School: "Secret",
    	}, &reply)
    	if err != nil {
    		panic(err)
    	}
    	log.Println(reply)
    }
    
    
  • 相关阅读:
    ES6获取页面所有页面标签名
    改变this对象的指向
    构造函数及原型
    全局对象this转为局部对象
    节点注意的问题
    Spark研究笔记17:设置 CVT
    Spark研究笔记15:资源 CVT
    Spark研究笔记13:Swing 组件类 CVT
    Spark研究笔记16:搜索 CVT
    Spark研究笔记19:插件体系开发 CVT
  • 原文地址:https://www.cnblogs.com/davis12/p/16286080.html
Copyright © 2020-2023  润新知