golang-网络编程

golang-网络编程_第1张图片
golang-网络编程_第2张图片
在这里插入图片描述
golang-网络编程_第3张图片
golang-网络编程_第4张图片
golang-网络编程_第5张图片
golang-网络编程_第6张图片
网络包发送解析基本过程:
osi七层在编程中可以简化为四层分别为:

  • 应用层
  • 传输层
  • ip网络层
  • 链路层
    golang-网络编程_第7张图片
    golang-网络编程_第8张图片
    golang-网络编程_第9张图片
    golang-网络编程_第10张图片
    golang-网络编程_第11张图片
    golang-网络编程_第12张图片
    小知识:
    netstat -anb 查看本机监听端口

golang-网络编程_第13张图片
golang-网络编程_第14张图片
golang-网络编程_第15张图片
实例:
golang-网络编程_第16张图片
golang-网络编程_第17张图片
golang-网络编程_第18张图片
golang-网络编程_第19张图片
标准输入代表键盘输入:
golang-网络编程_第20张图片
golang-网络编程_第21张图片
server.go

// net包提供了可移植的网络I/O接口,
// 包括TCP/IP、UDP、域名解析和Unix域socket
package main

import (
	"fmt"
	"net"
	_"io"
)

func process(conn net.Conn){
	// 循环接收客户发送的数据
	defer conn.Close()
	for {
		buf := make([]byte,1024)
		fmt.Println("服务器在等待客户端发送信息"+conn.RemoteAddr().String())
		// Read从conn中读取数据返回n为此数据的长度
		n,err := conn.Read(buf)
		if err != nil{
			fmt.Println("服务器端conn.Read err = :",err)
			return
		}
		fmt.Print(string(buf[:n]))
	}
}

func main(){
	fmt.Println("服务器开始监听...")
	// 返回在一个本地网络地址laddr上监听的Listener
	// 网络类型参数net必须是面向流的网络:"tcp"、"tcp4"、"tcp6"
	// "unix"或"unixpacket"
	listen,err := net.Listen("tcp","0.0.0.0:8888")
	defer listen.Close()

	if err != nil{
		fmt.Println("Listen err: ",err)
		return
	}

	for {
		fmt.Println("等待客户端来连接...")
		conn,err := listen.Accept()
		if err != nil{
			fmt.Println("Accept() err:",err)
			return
		}else{
			fmt.Printf("Accept() ok!=%v,client.address=%v\n",conn,conn.RemoteAddr())
			go process(conn)
		}
	}
}

client.go

package main

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

func main(){
	conn,err := net.Dial("tcp","127.0.0.1:8888")
	if err != nil{
		fmt.Println("Dial err:",err)
	}
	fmt.Println("连接成功! = ",conn)

	// os.stdin 代表标准输入(终端)
	reader := bufio.NewReader(os.Stdin)

	// 从终端读取一行用户输入
	line,err := reader.ReadString('\n')
	if err != nil{
		fmt.Println("ReadString err:",err)
	}

	// 从连接中发送数据
	n,err := conn.Write([]byte(line))
	if err != nil{
		fmt.Println("conn.Write err:",err)
	}
	fmt.Printf("客户端发送了 %d 个字节并退出",n)
}

ReadString()写入的数据是带\n的有时候需要去掉就用下边这个函数
golang-网络编程_第22张图片
优化版本:
server.go

package main

import (
	"fmt"
	"net"
)

func con(conn net.Conn){
	defer conn.Close()
	// 定义一个1024长度的切片用来接收客户端的数据
	// 循环从conn连接中读取信息
	for {
		buf := make([]byte,1024)
		n,err := conn.Read(buf)
		if err != nil{
			fmt.Println("conn ")
		}
		fmt.Println("接收信息为: ")
		fmt.Println(string(buf[:n]))
		fmt.Println("等待连接")
	}
}

func main(){
	// 首先定义返回一个服务端的ip和端口
	// 端口 0-65535
	listen,err := net.Listen("tcp","0.0.0.0:9999")
	if err != nil{
		fmt.Println("listen err:",err)
	}

	// 循环接收client连接
	for{
		// 等待并返回一个连接到服务端地址ip的连接conn
		conn,err := listen.Accept()
		fmt.Println("连接建立fpx.no1")		
		defer conn.Close()
		if err != nil{
		fmt.Println("listen.Accept() err:",err)
		}
		go con(conn)
	}
}

client.go

package main

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

func main(){
	// Dial在指定的网络上连接指定的地址。参见Dial函数获取网络和地址参数的描述。
	conn,err := net.Dial("tcp","0.0.0.0:9999")
	if err != nil{
		fmt.Println("net.Dial err:",err)
	}

	// NewReader创建一个缓冲区os.Stdin为标准输入(键盘输入)
	fmt.Println("请写入将要发送给server的数据fpx.no1")
	// 创建一个缓冲区
	reader := bufio.NewReader(os.Stdin)
	for {
		line, err := reader.ReadString('\n')
		// 使用ReadString写入的数据是带有空格或者换行符的需要去掉方便判断
		// strings.Trim() 返回将s前后端所有cutset包含的utf-8码值都去掉的字符串。
		line = strings.Trim(line," \r\n")
		if line == "exit"{
			fmt.Println("退出```")
			// return 退出当前函数 break退出当前循环
			return
		}

		if err != nil{
			fmt.Println("reader.ReadString() err:",err)
		}

		fmt.Println("即将发送fpx.no1")
		n,err := conn.Write([]byte(line))
		if err != nil{
			fmt.Println("conn.Write() err:",err)
		}
		fmt.Printf("发送完毕,发送信息长度%d字节\n",n)
	}
}

你可能感兴趣的:(go)