Go 之网络编程

客户端client

package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"
)

//客户端

func main() {
	conn,err := net.Dial("tcp","127.0.0.1:20000")
	if err !=nil{
		fmt.Println("err:",err)
		return
	}
	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
		}
		_,err:= conn.Write([]byte(inputInfo))
		if err !=nil{
			return
		}
		buf := [512]byte{}
		n,err := conn.Read(buf[:])
		if err !=nil{
			fmt.Println("recv failed err :",err)
			return
		}
		fmt.Println(string(buf[:n]))
	}
}

  

 

服务端 server

package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"
)

//服务端

func processlist(conn net.Conn)  {
	defer conn.Close()
	inputReader:= bufio.NewReader(os.Stdin)
	for  {
		reader:=bufio.NewReader(conn)
		var buf [128]byte
		n,err := reader.Read(buf[:]) //读取数据
		if err !=nil{
			fmt.Println("read from client failed err :",err)
			break
		}
		recvStr := string(buf[:n])
		fmt.Println("收到client端发送过来的数据:",recvStr)

		//读取终端数输入
		input,_ := inputReader.ReadString('\n')
		inputInfo:= strings.Trim(input,"\r\n")
		if strings.ToUpper(inputInfo) == "Q"{
			return
		}
		conn.Write([]byte(inputInfo)) //在发送回去

	}

}


func main() {
	listen,err := net.Listen("tcp","127.0.0.1:20000")
	if err !=nil{
		fmt.Println("listen failed err ",err)
		return
	}
	for  {
		conn,err :=listen.Accept()
		if err !=nil{
			fmt.Println("Accept failed err :",err)
			return
		}
		go processlist(conn)
	}

}

  

 

出现粘包问题的处理方式,

自己封装编码包

package proto

import (
	"bufio"
	"bytes"
	"encoding/binary"
)

//编码

func Encode(msg string) ([]byte,error) {
	var length = int32(len(msg))
	var pkg = new(bytes.Buffer)
	//写入消息头
	err := binary.Write(pkg,binary.LittleEndian,length)
	if err !=nil{
		return nil,err
	}
//	写入消息实体
	err = binary.Write(pkg,binary.LittleEndian,[]byte(msg))
	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
	}

	if int32(reader.Buffered()) < length+4{
		return "",err
	}
//	读取真正的消息数据
	pack := make([]byte,int(4+length))
	_,err = reader.Read(pack)
	if err !=nil{
		return "",nil
	}
	return string(pack[4:]),nil
}

  

客户端client

package main

import (
	"fmt"
	"lesson26/tcp/demo2/proto"
	"net"
)

//客户端


func main() {
	conn,err :=net.Dial("tcp","127.0.0.1:20000")
	if err !=nil{
		fmt.Println("dial failed err:",err)
		return
	}
	defer conn.Close()
	for i:=0;i<20;i++ {
		msg := `------hello,everyone!`
		data,err := proto.Encode(msg)
		if err !=nil{
			fmt.Println("encode failed err :",err)
			return
		}
		conn.Write(data)
	}
}

  

 

服务端server

package main

import (
	"bufio"
	"fmt"
	"io"
	"lesson26/tcp/demo2/proto"
	"net"
)

//服务端

func processlist(conn net.Conn)  {
	defer conn.Close()
	//var buf [1024]byte
	reader := bufio.NewReader(conn)
	for{
		//n,err := reader.Read(buf[:])
		msg,err := proto.Decode(reader)
		if err == io.EOF{
			break
		}
		if err !=nil{
			fmt.Println("read failed err :",err)
			return
		}
		//recvStr := string(buf[:n])
		fmt.Println("收到client的数据:",msg)
	}
}

func main() {
	listen,err := net.Listen("tcp","127.0.0.1:20000")
	if err !=nil{
		fmt.Println("listen failed err:",err)
		return
	}
	defer listen.Close()
	for  {
		conn,err := listen.Accept()
		if err !=nil{
			fmt.Println("accept failed err :",err)
			return
		}
		go processlist(conn)
	}
}

  

 

posted @ 2021-01-22 16:52  pebblecome  阅读(62)  评论(0)    收藏  举报