zoukankan      html  css  js  c++  java
  • golang之网络编程

    基本介绍:

      网络编程有两种:

        1)tcp socket编程,是网络编程的主流。之所以叫tcp socket编程,是因为底层是基于tcp/ip协议的

        2)b/s结构的http编程,我们使用浏览器去访问服务器时,使用的就是http协议,而http底层依旧是用tcp socket实现的

    tcp socket编程的快速入门:

      1.服务端的处理流程

        1)监听接口:8888

        2)接收客户端的tcp链接,建立客户端和服务端的链接

        3)创建goroutine,处理该链接的请求

      2.客户端的处理流程

        1)建立与服务端的链接

        2)发送请求数据,接收服务端返回的结果数据

        3)关闭链接

    服务端代码:

    package main
    
    import (
        "fmt"
        "net"
    )
    
    func process(conn net.Conn) {
        // 这里循环接收客户端发送的数据
        defer conn.Close()
        for {
            // 创建一个新切片
            buf := make([]byte, 1024)
            fmt.Printf("服务器在等待客户端%s 发送信息
    ", conn.RemoteAddr().String())
            n, err := conn.Read(buf) // 从conn中读取
            if err != nil {
                fmt.Printf("客户端退出 err=%v
    ", err)
                return
            }
            fmt.Print(string(buf[:n]))
        }
    }
    
    func main() {
        fmt.Println("服务器开始监听...")
        listen, err := net.Listen("tcp", "0.0.0.0:8888")
        if err != nil {
            fmt.Println("listen err=", err)
            return
        }
        defer listen.Close() // 延时关闭
        // 循环等待客户端来链接
        for {
            fmt.Println("等待客户端来链接...")
            conn, err := listen.Accept()
            if err != nil {
                fmt.Println("Accept() err=", err)
            } else {
                fmt.Printf("Accept() suc con=%v 客户端 ip=%v
    ", conn, conn.RemoteAddr().String())
            }
            // 这里准备起一个协程,为客户端服务
            go process(conn)
        }
    }

    客户端代码:

    package main
    
    import (
        "bufio"
        "fmt"
        "net"
        "os"
        "strings"
    )
    
    func main() {
        conn, err := net.Dial("tcp", "192.168.2.229:8888")
        if err != nil {
            fmt.Println("client dial err=", err)
            return
        }
        // 功能一:客户端可以发送单行数据,然后退出
        reader := bufio.NewReader(os.Stdin) // os.Stdin代表标准输入
        for {
            // 从终端读取一行用户输入,并准备发送给服务器
            line, err := reader.ReadString('
    ')
            if err != nil {
                fmt.Println("readString err=", err)
            }
            line = strings.Trim(line, " 
    ")
            if line == "exit" {
                fmt.Println("客户端退出")
                return
            }
            // 再将line发送给服务器
            _, err = conn.Write([]byte(line + "
    "))
            if err != nil {
                fmt.Println("conn.Write err=", err)
            }
        }
        //fmt.Printf("客户端发送了 %d 字节的数据,并退出", n)
    }
    人生就是要不断折腾
  • 相关阅读:
    块存储、文件存储、对象存储的区别
    brk 和 sbrk 区别
    【转】海量数据处理:十道面试题与十个海量数据处理方法总结
    C++ STL 里为什么不维护一个 size 成员变量?
    C++对象内存分布详解(包括字节对齐和虚函数表)
    虚函数实现原理
    关于Ubuntu中Could not get lock /var/lib/dpkg/lock解决方案
    Jerasure 1.2A 中的 C 函数 tips
    C++ qsort() 函数调用时实参与形参不兼容的问题解决
    C语言位运算符:与、或、异或、取反、左移与右移详细介绍
  • 原文地址:https://www.cnblogs.com/xiangxiaolin/p/12364580.html
Copyright © 2011-2022 走看看