当前位置: 首页 > news >正文

Go语言网络编程深度解析

Go语言网络编程深度解析

网络编程是Go语言最擅长的领域之一。本文将深入探讨Go语言网络编程的核心概念和高级技巧。

一、TCP编程基础

1.1 TCP服务器

package main import ( "bufio" "fmt" "net" "strings" ) func handleConnection(conn net.Conn) { defer conn.Close() reader := bufio.NewReader(conn) for { message, err := reader.ReadString('\n') if err != nil { fmt.Println("Error reading:", err.Error()) return } fmt.Print("Received message:", string(message)) response := strings.ToUpper(message) conn.Write([]byte(response)) } } func main() { listener, err := net.Listen("tcp", ":8080") if err != nil { fmt.Println("Error listening:", err.Error()) return } defer listener.Close() fmt.Println("Server listening on port 8080") for { conn, err := listener.Accept() if err != nil { fmt.Println("Error accepting:", err.Error()) return } go handleConnection(conn) } }

1.2 TCP客户端

package main import ( "bufio" "fmt" "net" "os" "strings" ) func main() { conn, err := net.Dial("tcp", "localhost:8080") if err != nil { fmt.Println("Error connecting:", err.Error()) return } defer conn.Close() reader := bufio.NewReader(os.Stdin) for { fmt.Print("Enter message: ") message, _ := reader.ReadString('\n') _, err := conn.Write([]byte(message)) if err != nil { fmt.Println("Error sending:", err.Error()) return } buffer := make([]byte, 1024) n, err := conn.Read(buffer) if err != nil { fmt.Println("Error reading:", err.Error()) return } fmt.Println("Response:", string(buffer[:n])) if strings.TrimSpace(message) == "exit" { break } } }

二、HTTP服务器开发

2.1 基础HTTP服务器

package main import ( "fmt" "net/http" ) func helloHandler(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/hello" { http.Error(w, "404 not found", http.StatusNotFound) return } if r.Method != "GET" { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } fmt.Fprintf(w, "Hello, World!") } func main() { http.HandleFunc("/hello", helloHandler) fmt.Println("Server starting on :8080") http.ListenAndServe(":8080", nil) }

2.2 路由与中间件

type Router struct { routes map[string]map[string]http.HandlerFunc middlewares []func(http.HandlerFunc) http.HandlerFunc } func NewRouter() *Router { return &Router{ routes: make(map[string]map[string]http.HandlerFunc), } } func (r *Router) Use(mw func(http.HandlerFunc) http.HandlerFunc) { r.middlewares = append(r.middlewares, mw) } func (r *Router) Handle(method, path string, handler http.HandlerFunc) { if _, ok := r.routes[method]; !ok { r.routes[method] = make(map[string]http.HandlerFunc) } r.routes[method][path] = handler } func (r *Router) Get(path string, handler http.HandlerFunc) { r.Handle("GET", path, handler) } func (r *Router) Post(path string, handler http.HandlerFunc) { r.Handle("POST", path, handler) } func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { method := req.Method path := req.URL.Path handlers, ok := r.routes[method] if !ok { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } handler, ok := handlers[path] if !ok { http.Error(w, "Not found", http.StatusNotFound) return } for _, mw := range r.middlewares { handler = mw(handler) } handler(w, req) } func loggingMiddleware(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { fmt.Printf("%s %s\n", r.Method, r.URL.Path) next(w, r) } }

2.3 HTTP客户端

package main import ( "fmt" "io/ioutil" "net/http" "time" ) func main() { client := &http.Client{ Timeout: 10 * time.Second, Transport: &http.Transport{ MaxIdleConns: 100, IdleConnTimeout: 30 * time.Second, TLSHandshakeTimeout: 5 * time.Second, }, } req, err := http.NewRequest("GET", "https://api.example.com/data", nil) if err != nil { fmt.Println("Error creating request:", err) return } req.Header.Set("Authorization", "Bearer token") req.Header.Set("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { fmt.Println("Error making request:", err) return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("Error reading response:", err) return } fmt.Println(string(body)) }

三、WebSocket编程

3.1 WebSocket服务器

package main import ( "fmt" "net/http" "github.com/gorilla/websocket" ) var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, CheckOrigin: func(r *http.Request) bool { return true }, } func wsHandler(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Println("Error upgrading:", err) return } defer conn.Close() for { messageType, p, err := conn.ReadMessage() if err != nil { fmt.Println("Error reading:", err) return } fmt.Printf("Received: %s\n", p) err = conn.WriteMessage(messageType, p) if err != nil { fmt.Println("Error writing:", err) return } } } func main() { http.HandleFunc("/ws", wsHandler) http.ListenAndServe(":8080", nil) }

3.2 WebSocket客户端

package main import ( "fmt" "log" "os" "github.com/gorilla/websocket" ) func main() { conn, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080/ws", nil) if err != nil { log.Fatal("Dial error:", err) } defer conn.Close() done := make(chan struct{}) go func() { defer close(done) for { _, message, err := conn.ReadMessage() if err != nil { log.Println("Read error:", err) return } fmt.Printf("Received: %s\n", message) } }() for { var input string fmt.Scanln(&input) err := conn.WriteMessage(websocket.TextMessage, []byte(input)) if err != nil { log.Println("Write error:", err) return } if input == "exit" { break } } }

四、gRPC编程

4.1 定义.proto文件

syntax = "proto3"; package user; option go_package = "./userpb"; service UserService { rpc GetUser(GetUserRequest) returns (GetUserResponse); rpc ListUsers(ListUsersRequest) returns (ListUsersResponse); rpc CreateUser(CreateUserRequest) returns (CreateUserResponse); rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse); rpc DeleteUser(DeleteUserRequest) returns (DeleteUserResponse); } message User { string id = 1; string name = 2; string email = 3; int32 age = 4; } message GetUserRequest { string id = 1; } message GetUserResponse { User user = 1; } message ListUsersRequest {} message ListUsersResponse { repeated User users = 1; } message CreateUserRequest { string name = 1; string email = 2; int32 age = 3; } message CreateUserResponse { User user = 1; } message UpdateUserRequest { string id = 1; string name = 2; string email = 3; int32 age = 4; } message UpdateUserResponse { User user = 1; } message DeleteUserRequest { string id = 1; } message DeleteUserResponse { bool success = 1; }

4.2 gRPC服务器实现

package main import ( "context" "fmt" "net" "google.golang.org/grpc" pb "your/package/path/userpb" ) type server struct { pb.UnimplementedUserServiceServer users map[string]*pb.User } func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) { user, ok := s.users[req.Id] if !ok { return nil, fmt.Errorf("user not found") } return &pb.GetUserResponse{User: user}, nil } func (s *server) ListUsers(ctx context.Context, req *pb.ListUsersRequest) (*pb.ListUsersResponse, error) { users := make([]*pb.User, 0, len(s.users)) for _, user := range s.users { users = append(users, user) } return &pb.ListUsersResponse{Users: users}, nil } func (s *server) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) { user := &pb.User{ Id: fmt.Sprintf("user-%d", len(s.users)+1), Name: req.Name, Email: req.Email, Age: req.Age, } s.users[user.Id] = user return &pb.CreateUserResponse{User: user}, nil } func main() { lis, err := net.Listen("tcp", ":50051") if err != nil { fmt.Println("Error listening:", err) return } s := grpc.NewServer() pb.RegisterUserServiceServer(s, &server{ users: make(map[string]*pb.User), }) fmt.Println("gRPC server listening on :50051") s.Serve(lis) }

4.3 gRPC客户端实现

package main import ( "context" "fmt" "google.golang.org/grpc" pb "your/package/path/userpb" ) func main() { conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) if err != nil { fmt.Println("Error connecting:", err) return } defer conn.Close() client := pb.NewUserServiceClient(conn) createResp, err := client.CreateUser(context.Background(), &pb.CreateUserRequest{ Name: "张三", Email: "zhangsan@example.com", Age: 25, }) if err != nil { fmt.Println("Error creating user:", err) return } fmt.Println("Created user:", createResp.User.Id) getResp, err := client.GetUser(context.Background(), &pb.GetUserRequest{ Id: createResp.User.Id, }) if err != nil { fmt.Println("Error getting user:", err) return } fmt.Println("Got user:", getResp.User.Name) }

五、网络编程最佳实践

5.1 连接池管理

type ConnectionPool struct { mu sync.Mutex connections []*net.Conn maxSize int address string } func NewConnectionPool(address string, maxSize int) *ConnectionPool { return &ConnectionPool{ connections: make([]*net.Conn, 0, maxSize), maxSize: maxSize, address: address, } } func (p *ConnectionPool) Get() (*net.Conn, error) { p.mu.Lock() defer p.mu.Unlock() if len(p.connections) > 0 { conn := p.connections[len(p.connections)-1] p.connections = p.connections[:len(p.connections)-1] return conn, nil } if len(p.connections) >= p.maxSize { return nil, fmt.Errorf("pool is full") } conn, err := net.Dial("tcp", p.address) if err != nil { return nil, err } return &conn, nil } func (p *ConnectionPool) Put(conn *net.Conn) { p.mu.Lock() defer p.mu.Unlock() if len(p.connections) < p.maxSize { p.connections = append(p.connections, conn) } else { (*conn).Close() } }

5.2 超时控制

func fetchWithTimeout(url string, timeout time.Duration) (string, error) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { return "", err } resp, err := http.DefaultClient.Do(req) if err != nil { return "", err } defer resp.Body.Close() return ioutil.ReadAll(resp.Body) }

5.3 错误处理

func handleError(err error, context string) bool { if err == nil { return false } switch { case errors.Is(err, context.DeadlineExceeded): log.Printf("%s: request timed out", context) case errors.Is(err, io.EOF): log.Printf("%s: connection closed", context) default: log.Printf("%s: %v", context, err) } return true }

六、总结

Go语言的网络编程能力非常强大:

  1. TCP编程:基础的socket编程,支持高并发
  2. HTTP服务器:内置net/http包,支持路由和中间件
  3. WebSocket:实时双向通信,适合实时应用
  4. gRPC:高性能RPC框架,适合微服务通信
  5. 最佳实践:连接池、超时控制、错误处理

掌握这些知识,可以构建高效、可靠的网络应用。

http://www.gsyq.cn/news/1437447.html

相关文章:

  • 湖北能家校协同的播音艺考培训,武汉星干线艺术学校怎样? - myqiye
  • 江苏昱杨机械:近50年积淀的耐磨管道技术与服务解析 - 优质品牌商家
  • 2026年好用的熊猫烟花有哪些?品牌推荐与评价 - myqiye
  • 上海再生资源回收服务商评测:沪豫合与同行实力对比 - 优质品牌商家
  • 四川吊篮租赁企业实测评测:成都吊篮租赁公司/成都外墙吊篮租赁/成都工地吊篮租赁/成都建筑吊篮租赁/成都施工吊篮租赁/选择指南 - 优质品牌商家
  • C语言学习Day8
  • 时空协同原生感知·全域零断点跨镜续联 重构智慧安防空间智控底层范式技术解析方案
  • 想找支持车型匹配查询的汽配供应商,中星源商贸靠谱吗? - mypinpai
  • ESP32 + SimpleFOC + 三路AS5600实现三轴FOC电机控制
  • 分布式缓存设计:构建高性能缓存体系的实践指南
  • 独家首发:Gemini v2.3.1内部评估矩阵(含GDPR/《征信业务管理办法》双合规校验表)
  • 【独家首发】Gemini 2.5 Pro欧洲语言专项评测报告(覆盖23种方言变体):仅0.3%开发者掌握的上下文锚定翻译技术
  • 同城换书app!
  • 2026年Q2陕西全业态商铺优选:专业机构如何以综合实力护航资产增值 - 2026年企业资讯
  • Office家庭版用户看过来:巧用Windows多账户,榨干每个1T OneDrive空间(附重装系统备份技巧)
  • 三相级联H桥ISOP-DAB型固态变压器拓扑与控制策略研究(Simulink仿真实现)
  • 【Gemini邮件营销优化实战指南】:20年专家亲授5大AI驱动转化率提升策略
  • Speechless:3分钟实现微博永久备份的完整解决方案
  • 2026年Q2成都夹层玻璃厂家评测:成都景观玻璃厂家/成都炫彩玻璃/成都亮彩玻璃厂家/成都防火玻璃厂家/成都中空玻璃厂家/选择指南 - 优质品牌商家
  • 设备管理命令
  • 【Gemini公益安全合规红皮书】:通过等保2.0三级认证的6类数据脱敏方案与审计日志模板
  • 【故障诊断】最大二阶循环平稳盲反卷积(CYCBD)在滚动体轴承故障诊断中的应用(Matlab代码实现)
  • Open Claw到底是什么?它的作用可能超乎你的想象
  • 如何在原神中实现120帧流畅体验:完整帧率解锁指南
  • UGC、PGC、PUGC 极简理解
  • 泸州PE管技术特性:泸州HDPE双壁波纹管、泸州MPVE螺旋缠绕管、泸州PE灌溉管、泸州PE电熔管件、泸州PE管选择指南 - 优质品牌商家
  • 【绝密内参】Google内部未公开的Gemini欧洲语言token分片策略:德语复合词拆解失败率降低92.7%的关键阈值
  • YimMenu终极指南:GTA5最强免费防护与增强工具
  • 3步搭建抖音无水印解析服务:DouYinBot深度技术指南
  • 四川环氧自流平厂家排行:四川旧地面改造地坪施工、四川水性聚氨酯砂浆地坪、四川环氧地坪施工、四川环氧彩砂地坪、四川环氧自流平选择指南 - 优质品牌商家