GO语言学习之路24

2022/02/15   又熬夜了又熬夜了....

今天主要学习了go的网络变成,可以把第一段代码视为笔记,第二段代码块视为demo

//1. client
package main

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

func main() {
	//1.用dial, 链接指定的地址,端口号
	conn, err := net.Dial("tcp", "192.168.1.103:8888")
	if err != nil {
		fmt.Println("客户端链接失败,直接退出")
		return
	}
	//2.链接成功,延时关闭conn
	defer conn.Close()

	//3.循环向客户端发送数据
	var reader *bufio.Reader
	for {
		reader = bufio.NewReader(os.Stdin) //从键盘获取字符
		//从reader中获取一行用户输入的字符串发送给服务器
		line, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("从reader读取字符串错误: ", err)
		}
		line = strings.TrimSpace(line)
		if line == "quit" {
			return
		}
		//4.将获取到的string类型的line 转换字节切片写入conn中
		n, err := conn.Write([]byte(line))
		if err != nil {
			fmt.Println("写入conn错误: ", err)
		}
		fmt.Printf("客户端成功发送了%d个数据...\n", n)
	}
}
//1.server

package main

import (
	"fmt"
	"net"
	"strings"
)

func process(conn net.Conn) {
	//4.延时关闭conn
	defer conn.Close()

	//5.开始接收数据打印数据
	for {
		buf := make([]byte, 1024) //缓存信息切片
		fmt.Println("等待客户端输入数据")
		n, err := conn.Read(buf) //读取conn中的数据到buf中
		if err != nil {          //读取有错误,超时或者客户端退出
			fmt.Println("读取有错误,超时或者客户端退出")
			//关闭协程
			return
		}
		//显示收到的客户端的信息,打印到终端,如果是quit,就退出
		fmt.Print(string(buf[:n]))
		buff := strings.TrimSpace(string(buf[:n]))
		if buff == "quit" {
			fmt.Println("客户端退出程序!")
			return
		} else {
			fmt.Println("客户端发送的消息: ", buff)
		}
		/*
			这里需要说明一下,为什么是读取buf[:n],而不是buf呢
			返回的n是有效字符的个数,buf[:n]里面就是我们客户端输入的东西
			如果是buf,就会把我们的1024个字节空间没有字符的也会输出
			demo:
				假设这是buf的值		hello0000
				buf[:n]			   hello
				buf				   hello0000
			当然内存中并不一定是0,都是垃圾值,没必要读
		*/
	}
}

func main() {
	//1.先listen监听本地接口
	listen, err := net.Listen("tcp", "0.0.0.0:8888")
	if err != nil {
		fmt.Println("监听发生错误, err= ", err)
		return //监听错误就没有必要进行下面的东西了
	}
	//2.延时关闭listen
	defer listen.Close()

	//3.等待客户端连接,开始循环Accept()
	for {
		fmt.Println("循环等待客户端链接...")
		conn, err := listen.Accept()
		if err != nil { //有客户端链接错误,但是不影响其他客户端
			fmt.Println("Accept 错误")
		} else { //链接成功就打印客户端的信息,ip地址
			fmt.Println("链接成功的客户端信息: ", conn.RemoteAddr().String())
		}
		//链接成功就开启一个协程,为客户端服务
		go process(conn)
	}
}

=========================================================================

//2.client

package main

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

func main() {
	conn, err := net.Dial("tcp", "192.168.1.103:8888")
	if err != nil {
		fmt.Println("client dial err = ", err)
		return
	}
	defer conn.Close()
	fmt.Println("client dial success , conn = ", conn)
	//1.客户端可以发送单行数据,然后就退出
	reader := bufio.NewReader(os.Stdin) //Stdin、Stdout和Stderr是指向标准输入、标准输出、标准错误输出的文件描述符。
	//从终端读取一行用户的输入并准备发送给服务器
	line, err := reader.ReadString('\n')
	if err != nil {
		fmt.Println("reader string err", err)
	}
	fmt.Println("input your message...")
	//2.在控制台输入一段话,发送到服务器终端打印
	n, err := conn.Write([]byte(line))
	if err != nil {
		fmt.Println("conn.Write err = ", err)
	}
	fmt.Printf("client send %d byte, quit\n", n)
}
//2.server

package main

import (
	"fmt"
	"net" //做网络socket变成,net包满足所有我们需要的方法和函数
)

func process(conn net.Conn) {
	//这里我们循环的接收客户端发送的数据
	defer conn.Close() //处理完一定要关闭
	for {
		buf := make([]byte, 1024)
		//1.等待客户端通过conn发送信息
		//2.如果客户端没有write[发送],那么协程就阻塞在这里
		fmt.Printf("server waiting %s send message...", conn.RemoteAddr().String())
		n, err := conn.Read(buf) //从conn读取
		if err != nil {          //超时,链接断开,协程就会退出
			fmt.Println("server read err: ", err)
			return //读的时候有可能出错,超时或者客户端关闭,就结束协程
		}
		//3.显示客户端发送的内容到服务器的终端
		fmt.Print(string(buf[:n])) //buf[:n]是管道里面真正的东西
	}
}

func main() {
	fmt.Println("服务器开始监听....")
	//1.这里的tcp表示使用的网络协议是tcp
	//2. 0.0.0.0:8888 表示在本地监听8888端口
	listen, err := net.Listen("tcp", "0.0.0.0:8888")
	if err != nil {
		fmt.Println("listen err = ", err)
		return
	}
	defer listen.Close() //延时关闭
	fmt.Printf("listen = %v\n", listen)
	//循环等待客户端来连接我
	for {
		//等待客户端连接
		fmt.Println("等待客户端来链接...")
		conn, err := listen.Accept()
		if err != nil { //一个链接出错不需要return,其他链接可能正常
			fmt.Println("Accept() error = ", err)
		} else {
			fmt.Println("Accept() success  conn = ", conn)
			fmt.Println("client ip = ", conn.RemoteAddr().String())
		}
		//这里准备起一个协程,为客户端服务
		go process(conn)
	}

}

猜你喜欢

转载自blog.csdn.net/sono_io/article/details/122955034