Golang--网络编程
1、概念
网络编程:把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息、共享数据、软件、数据信息等资源。
客户端(Client)
客户端是请求服务的计算机或程序,它可以是桌面应用、移动应用或网页应用。客户端通常负责用户界面的呈现和用户输入的处理。用户通过客户端向服务器发送请求,通常包括想要访问的数据或资源的具体信息。例如,当你在浏览器中输入一个网址时,浏览器就是客户端,它向相应的服务器发送请求来获取页面信息。
服务器端(Server)
服务器端是提供服务的计算机或程序,它接收来自客户端的请求并做出响应。服务器通常负责处理数据、运行业务逻辑、存储数据和管理网络资源。响应可以是所请求的数据、处理结果,或者是其他要求的资源。例如,当服务器接收到来自浏览器的请求时,它会查找相应的网页文件并将其发送回客户端。
设备之间在网络中进行数据的传输/接收数据。
通信两个重要的要素:IP + PORT
设备之间进行传输的时候,必须遵照一定的规则 ----> 通信协议:
TCP协议:可靠的
1、建立连接:三次握手
2、释放连接:
UDP协议:不可靠的
2、TCP编程 -- 创建客户端
net包
Go语言标准库文档中文版 | Go语言中文网 | Golang中文社区 | Golang中国
Dial函数("net"):
package main import ( "fmt" "net" // 网络包 ) func main(){ //打印: fmt.Println("客户端启动中...") //调用Dial函数:参数:协议、IP、端口号 conn,err := net.Dial("tcp","127.0.0.1:8888") //协议、IP、端口号 if err != nil{// 连接失败 fmt.Println("客户端连接失败:err:",err) return } fmt.Println("连接成功,conn=",conn) }
3、TCP编程 -- 创建服务器端
进行监听:
Listen函数("net"):package main import ( "fmt" "net" // 网络包 ) func main(){ //打印: fmt.Println("服务器端启动中...") //进行监听:需要指定服务器端TCP协议,服务器端的IP + PORT listen,err := net.Listen("tcp","127.0.0.1:8888") //协议、IP、端口号 if err != nil{// 监听失败 fmt.Println("监听失败:err:",err) return } //监听成功,等待客户端连接 //循环等待客户端连接 for { conn,err := listen.Accept() // 等待客户端连接 if err!= nil{ fmt.Println("客户端连接失败:err:",err) return } fmt.Printf("等待连接成功,conn=%v,接收到的客户端信息: %v \n",conn,conn.RemoteAddr().String()) } }
4、TCP编程 -- 连接测试
运行时注意:需要先启动服务器端,然后启动客户端进行访问:
5、TCP编程 -- 发送终端数据
通过客户端发送单行数据,然后退出:
客户端:package main import ( "fmt" "net" // 网络包 "bufio" // 缓冲包 "os" // 操作系统包 ) func main(){ //打印: fmt.Println("客户端启动中...") //调用Dial函数:参数:协议、IP、端口号 conn,err := net.Dial("tcp","127.0.0.1:8888") //协议、IP、端口号 if err != nil{// 连接失败 fmt.Println("客户端连接失败:err:",err) return } fmt.Println("连接成功,conn=",conn) //通过客户端发送单行数据,然后退出: reader := bufio.NewReader(os.Stdin) // 读取用户输入的内容 //从终端读取一行用户输入,并准备发送给服务器 str, err := reader.ReadString('\n') // 读取用户输入的内容 if err!= nil{ fmt.Println("readString err:",err) } //发送数据: n,err := conn.Write([]byte(str)) // 发送数据 if err!= nil{ fmt.Println("conn.Write err:",err) } fmt.Printf("发送了%d字节的数据,并退出\n",n) }
服务器端:
package main import ( "fmt" "net" // 网络包 ) func process(conn net.Conn){ defer conn.Close() // 关闭连接 for{ //创建一个切片,用于存储读取到的客户端发送的数据 buf := make([]byte,1024) //从conn连接中读取数据 n,err := conn.Read(buf) // 读取数据 if err!= nil{ fmt.Println("conn.Read err:",err) return } //显示客户端发送的内容到服务器端的终端 fmt.Print(string(buf[:n])) // 显示客户端发送的内容到服务器端的终端 //向客户端回复ok conn.Write([]byte("ok...\n")) // 回复客户端 } } func main(){ //打印: fmt.Println("服务器端启动中...") //进行监听:需要指定服务器端TCP协议,服务器端的IP + PORT listen,err := net.Listen("tcp","127.0.0.1:8888") //协议、IP、端口号 if err != nil{// 监听失败 fmt.Println("监听失败:err:",err) return } //监听成功,等待客户端连接 //循环等待客户端连接 for { conn,err := listen.Accept() // 等待客户端连接 if err!= nil{ fmt.Println("客户端连接失败:err:",err) return }else{ fmt.Printf("等待连接成功,conn=%v,接收到的客户端信息: %v \n",conn,conn.RemoteAddr().String()) } //准备一个协程,协程处理客户端服务请求 go process(conn) // 协程处理客户端服务请求,不同的客户端连接,需要不同的协程处理 } }