12.Go语言-网络编程

时间:2020-07-19 23:42:31   收藏:0   阅读:84

3.网络编程

3.1.TCP编程

package main

import (
	"bufio"
	"fmt"
	"net"
)

func process(conn net.Conn) {
	defer conn.Close()
	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
		}
		// 把接收数据转换string类型
		recvStr := string(buf[:n])
		fmt.Println("收到client端发来的数据:",recvStr)
		write, _ := conn.Write([]byte(recvStr))
		fmt.Println("发送数据量:",write, " 字节!")
	}
}

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 faield, err:", err)
			continue
		}
		// 启动一个goroutine处理连接
		go process(conn)
	}
}
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 {
		fmt.Print("请输入传输信息:")
		// 读取输入信息
		input, _ := inputReader.ReadString(‘\n‘)
		// \r\n 分割
		inputInfo := strings.Trim(input, "\r\n")
		// 如果输入Q推出
		if strings.ToUpper(inputInfo) == "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]))
	}
}

3.2.UDP编程

package main

import (
	"fmt"
	"net"
)

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

import (
	"fmt"
	"net"
)

func main() {
	// 创建udp连接套接字
	socket, err := net.DialUDP("udp", nil, &net.UDPAddr{
		IP:net.IPv4(0,0,0,0),
		Port:30000,
	})
	if err != nil {
		fmt.Println("连接服务端失败,err:",err)
		return
	}
	defer socket.Close()
	sendData := []byte("hello world")
	// 发送数据
	_, err = socket.Write(sendData)
	if err != nil {
		fmt.Println("发送数据失败,err:",err)
		return
	}
	data := make([]byte,4096)
	// 接收数据
	n, remoteAddr, err := socket.ReadFromUDP(data)
	if err != nil {
		fmt.Println("接收数据失败。err:",err)
		return
	}
	fmt.Printf("recv:%v  addr:%v  count:%v\n", string(data[:n]), remoteAddr, n)
}

3.3TCP粘包

package main

import (
	"bufio"
	"fmt"
	"io"
	"net"
)

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

func main() {
	listen, err := net.Listen("tcp", "127.0.0.1:30000")
	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)
			continue
		}
		go process(conn)
	}
}
package main

import (
	"fmt"
	"net"
)

func main() {
	conn, err := net.Dial("tcp","127.0.0.1:30000")
	if err != nil{
		fmt.Println("dial failed,err",err)
		return
	}
	defer conn.Close()
	for i:=0;i<20;i++ {
		msg := "hello,hi my name is Tom"
		conn.Write([]byte(msg))
	}
}
 my name is Tomhello,hi my name is Tomhello,hi my name is Tomhello,hi my name is Tomhello,hi my name is Tom
接收到client发来的数据: hello,hi my name is Tomhello,hi my name is Tomhello,hi my name is To my name is Tomhello,hi my name is Tomhello,hi my name is Tomhello,hi my name is Tomhello,hi my name is Tomhello,hi my name is Tomhello,hi my name is Tomhello,hi my name is Tomhello,hi my name is Tom

3.3.1为什么会出现粘包

3.3.2解决办法

package main

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

func Encode(message string) ([]byte, error){
	// 读取消息的长度,转换成int32类型(占4个字节)
	var length = int32(len(message))
	fmt.Printf("length:%v\n",length)// length:11
	var pkg = new(bytes.Buffer)
	//fmt.Println(pkg) //空对象
	// 写入消息头
	err := binary.Write(pkg, binary.LittleEndian, length)
	if err != nil {
		return nil, err
	}
	// 写入消息体
	err = binary.Write(pkg,binary.LittleEndian, []byte(message))
	if err != nil {
		return nil, err
	}
	fmt.Printf("message:%v\n",pkg)//message:hello world
	fmt.Println(pkg.Bytes())//[11 0 0 0 104 101 108 108 111 32 119 111 114 108 100]
	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

}

func main (){
	msg := "hello world"
	a,_ := Encode(msg)
	fmt.Printf("type:%T\n",a)
	// data, _:=Decode(a)
	// fmt.Println(data)
}
package main

import (
	"bufio"
	"fmt"
	"io"
	"mypro/tcp_stick/proto"
	"net"
)

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

func main() {
	listen, err := net.Listen("tcp", "127.0.0.1:30000")
	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)
			continue
		}
		go process(conn)
	}
}

package main

import (
	"fmt"
	"mypro/tcp_stick/proto"
	"net"
)

func main() {
	conn, err := net.Dial("tcp","127.0.0.1:30000")
	if err != nil{
		fmt.Println("dial failed,err",err)
		return
	}
	defer conn.Close()
	for i:=0;i<20;i++ {
		msg := "hello,hi my name is Tom"
		data, err := proto.Encode(msg)
		if err != nil {
			fmt.Println("encode msg failed, err:",err)
		}
		conn.Write(data)
	}
}
评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!