golang 的net包的网络编程 TCP | HTTP | RPC
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) }
分类:
golang
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南