cs note
  • 首页
  • 广告业务
    • RTA
  • 操作系统
    • 1.计算机系统漫游
    • 2.硬件结构
    • 3.内存管理
    • 4.进程管理
    • 5.文件系统
    • 6.设备管理
    • 7.网络系统
  • 网络
    • 高并发短链接
    • 网络编程
    • 网络通信
    • 网络协议详解
    • 网络与io模型
    • 网络io
    • 握手分手问题
    • 压测到网络IO
    • nio
    • osi七层参考模型
    • select,poole,poll详解
    • websocket
  • mysql
    • 一、基础
      • 1.1执行过程
      • 1.2存储过程
    • 二、索引
      • mysql索引
      • mysql索引优化1
      • mysql索引优化2
      • mysql索引优化3
    • 三、事务
    • 四、锁
      • 4.1锁详解
    • 五、日志
  • redis
    • 一、常见数据结构
      • 1.1数据类型
      • 1.2特殊数据类型
    • 二、线程模型 *
    • 三、持久化
      • 3.2主从同步
    • 四、锁
      • 4.1实现锁
    • 五、淘汰策略 *
    • 六、缓存
      • 6.1缓存一致性问题
      • 6.2缓存策略
  • kafka
    • 消息幂等通用方案
    • kafka基础使用
    • kafka集群搭建
    • kafka问题精选
    • mq常见问题
    • mq常见问题及解决方案
    • rabbitmq
  • 算法
    • 每日一题202312
    • 每日一题202401
    • 每日一题202402
    • 每日一题202403
    • LeetCode热题
由 GitBook 提供支持
在本页
  1. 网络

网络编程

最后更新于1年前

socket编程

Socket是应用层与TCP/IP协议族通信的中间软件抽象层。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket后面,对用户来说只需要调用Socket规定的相关函数,让Socket去组织符合指定的协议数据然后进行通信。

图解

### tcp协议

TCP/IP(Transmission Control Protocol/Internet Protocol) 即传输控制协议/网间协议,是一种面向连接(连接导向)的、可靠的、基于字节流的传输层(Transport layer)通信协议,因为是面向连接的协议,数据像水流一样传输,会存在黏包问题。

服务端

/**
 * Createby GoLand
 * User xzw jsjxzw@163.com
 * Date 2021/8/8
 * Time 上午10:27
 */

package main

import (
   bufio
   fmt
   io
   log
   net

   imooc.com/ccmouse/learngo/net/protocol
)

func main() {
   listen, err := net.Listen(tcp, 127.0.0.1:8080) // 监听端口
   if err != nil {
      log.Fatal(listen failed, err:, err)
   }
   for {
      conn, err := listen.Accept() // 建立连接
      if err != nil {
         log.Println(accept failed, err:, err)
         continue
      }
      go process(conn) // 启动一个 goroutine 处理连接
   }
}

func process(conn net.Conn) {
   defer conn.Close()
   for {
      reader := bufio.NewReader(conn)

      msg, err := protocol.Decode(reader)
      if err == io.EOF {
         return
      }
      if err != nil {
         log.Println(decode msg failed, err:, err)
         return
      }
      fmt.Println(收到client发来的数据:, msg)
      data, err := protocol.Encode(msg)
      if err != nil {
         log.Println(encode msg failed, err:, err)
         return
      }
      conn.Write(data)
   }
}

客户端

/**
 * Createby GoLand
 * User xzw jsjxzw@163.com
 * Date 2021/8/8
 * Time 上午10:35
 */

package main

import (
   bufio
   fmt
   io
   log
   net
   os
   strings

   imooc.com/ccmouse/learngo/net/protocol
)

func main() {
   conn, err := net.Dial(tcp, 127.0.0.1:8080)
   if err != nil {
      log.Fatal(err:, err)
   }
   defer conn.Close()
   inputReader := bufio.NewReader(os.Stdin)
   for {
      input, _ := inputReader.ReadString('\n') // 读取用户输入
      inputInfo := strings.Trim(input, \r\n)
      if strings.ToUpper(inputInfo) == Q { // 如果输入q就推出
         return
      }
      data, err := protocol.Encode(inputInfo)
      if err != nil {
         panic(err)
      }
      _, err = conn.Write(data) // 发送数据
      if err != nil {
         return
      }
      reader := bufio.NewReader(conn)
      msg, err := protocol.Decode(reader)
      if err == io.EOF {
         return
      }
      if err != nil {
         log.Println(decode msg failed, err:, err)
         return
      }
      fmt.Println(msg)
   }
}

粘包拆包

/**
 * Createby GoLand
 * User xzw jsjxzw@163.com
 * Date 2021/8/8
 * Time 上午10:48
 */

package protocol

import (
   bufio
   bytes
   encoding/binary
)

// 将消息编码
func Encode(message string) ([]byte, error) {
   // 读取消息的长度,转换成int32类型(占4个字节)
   var length = int32(len(message))
   var pkg = new(bytes.Buffer)
   // 写入消息头
   err := binary.Write(pkg, binary.LittleEndian, length) // binary.LittleEndian 小端序,低地址位存放低位字节
   if err != nil {
      return nil, err
   }
   // 写入消息实体
   err = binary.Write(pkg, binary.LittleEndian, []byte(message))
   if err != nil {
      return nil, err
   }
   return pkg.Bytes(), nil
}

// 解码消息
func Decode(reader *bufio.Reader) (string, error) {
   // 读取消息的长度
   lengthByte, _ := reader.Peek(4) // 读取前 4 个字节的数据
   lengthBuff := bytes.NewBuffer(lengthByte)
   var length int32
   err := binary.Read(lengthBuff, binary.LittleEndian, &length)
   if err != nil {
      return , err
   }
   // Buffered返回缓冲中现有的可读取的字节数
   if int32(reader.Buffered()) < length+4 {
      return , err
   }
   // 读取真正的消息
   pack := make([]byte, int(4+length))
   _, err = reader.Read(pack)
   if err != nil {
      return , err
   }
   return string(pack[4:]), nil
}

udp协议

用户数据报协议(User Datagram Protocol,缩写为UDP),又称用户数据报文协议,是一个简单的面向数据报(package-oriented)的传输层协议。UDP只提供数据的不可靠传递,它一旦把应用程序发给网络层的数据发送出去,就不保留数据备份(所以UDP有时候也被认为是不可靠的数据报协议)。UDP在IP数据报的头部仅仅加入了复用和数据校验。

服务端

/**
 * Createby GoLand
 * User xzw jsjxzw@163.com
 * Date 2021/8/8
 * Time 上午11:36
 */

package main

import (
   log
   net
)

func main() {
   listen, err := net.ListenUDP(udp, &net.UDPAddr{
      IP:   net.IPv4(0, 0, 0, 0),
      Port: 30000,
   })
   if err != nil {
      log.Println(listen failed, err:, err)
      return
   }
   defer listen.Close()
   for {
      var data [1024]byte
      n, addr, err := listen.ReadFromUDP(data[:]) // 接收数据
      if err != nil {
         log.Println(read udp failed, err:, err)
         continue
      }
      log.Printf(data:%v addr:%v count:%v\n, string(data[:n]), addr, n)
      _, err = listen.WriteToUDP(data[:n], addr) // 发送数据
      if err != nil {
         log.Println(write to udp failed, err:, err)
         continue
      }
   }
}

客户端

/**
 * Createby GoLand
 * User xzw jsjxzw@163.com
 * Date 2021/8/8
 * Time 上午11:43
 */

package main

import (
   fmt
   log
   net
)

func main() {
   socket, err := net.DialUDP(udp, nil, &net.UDPAddr{
      IP:   net.IPv4(0, 0, 0, 0),
      Port: 30000,
   })
   if err != nil {
      log.Println(连接服务器失败,err:, err)
      return
   }
   defer socket.Close()
   sendData := []byte(Hello server)
   _, err = socket.Write(sendData) // 发送数据
   if err != nil {
      log.Println(发送数据失败,err:, err)
      return
   }
   data := make([]byte, 4096)
   n, remoteAddr, err := socket.ReadFromUDP(data) // 接收数据
   if err != nil {
      log.Println(接收数据失败,err:, err)
      return
   }
   fmt.Printf(recv:%v addr:%v count:%v\n, string(data[:n]), remoteAddr, n)
}
网络通信——tcp/ip协议