当前位置: 首页 > article >正文

go网络编程

敬告:本文不讲解代码,只是把代码展示出来。

1、简单示例

1.1、服务端代码

package main

import (
	"fmt"
	"net"
)

func process(conn net.Conn) {
	// 处理客户端请求
	defer conn.Close() //关闭连接,如果不关闭会因为连接数不释放,导致服务器无法接收新的连接
	for {
		//创建新的切片
		buf := make([]byte, 1024)
		//读取客户端数据。如果客户端不 conn.Write(),conn.Read()会一直阻塞
		fmt.Printf("等待客户端发送数据...%v", conn.RemoteAddr())
		n, err := conn.Read(buf)
		if err != nil {
			fmt.Println("客户端连接断开:", err)
			break
		}
		//打印客户端发送的数据
		fmt.Print("客户端发送的数据:", string(buf[:n])) //[:n]一定要写,否则会打印多余的东西出来
	}
}
func main() {
	fmt.Println("服务器开始监听...")
	//net.Listen("tcp", "0.0.0.0:8888")
	//1.tcp 表示使用网络协议是 tcp
	//2. 0.0.0.0 表示监听 8888 端口
	listener, err := net.Listen("tcp", "0.0.0.0:8888")
	if err != nil {
		fmt.Println("服务器监听失败:", err)
		return
	}
	defer listener.Close()

	for {
		// 等待客户端连接
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println("服务器接收客户端连接失败:", err)
			continue
		} else {
			fmt.Println("服务器接收客户端连接成功:", conn.RemoteAddr())
		}
		// 处理客户端请求
		//go handleClient(conn)
		go process(conn)
	}
}

1.2、客户端代码

package main

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

func main() {
	conn, err := net.Dial("tcp", ":8888")
	if err != nil {
		fmt.Println("Error connecting to server:", err)
		return
	}
	//客户端可以发送单行数据到服务器,然后就退出
	reader := bufio.NewReader(os.Stdin) //os.Stdin是标准输入
	//从终端读取一行用户输入并准备发送给服务器
	line, err := reader.ReadString('\n')
	if err != nil {
		fmt.Println("Error reading input:", err)
	}
	//再讲line发送给服务器
	n, err := conn.Write([]byte(line))
	if err != nil {
		fmt.Println("conn.Write err=", err)
	}
	fmt.Printf("客户端发送了%d字节的数据,并退出", n)
}

1.3、运行结果查看

服务端运行

go run ../server/net1.go
服务器开始监听...

再打开一个窗口运行客户端程序

go run client/net1.go 

输入 hello test

hello test
客户端发送了11字节的数据,并退出
这时查看服务端程序的输出

服务端程序输出

服务器开始监听...
服务器接收客户端连接成功: 127.0.0.1:54263
等待客户端发送数据...127.0.0.1:54263客户端发送的数据:hello test
等待客户端发送数据...127.0.0.1:54263客户端连接断开: EOF

2、简单示例改进版代码

2.1、服务端改进代码

上述代码有个瑕疵就是每次客户端退出就会输出 EOF ,为了避免这个输出,可以使用如下代码处理

	if err == io.EOF {
		fmt.Println("客户端连接断开")
		break
	}

完整的改进版 server 端代码如下,客户端代码不变

package main

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

func process(conn net.Conn) {
	// 处理客户端请求
	defer conn.Close() //关闭连接,如果不关闭会因为连接数不释放,导致服务器无法接收新的连接
	for {
		//创建新的切片
		buf := make([]byte, 1024)
		//读取客户端数据。如果客户端不 conn.Write(),conn.Read()会一直阻塞
		fmt.Printf("等待客户端发送数据...%v", conn.RemoteAddr())
		n, err := conn.Read(buf)

		if err == io.EOF {
			fmt.Println("客户端连接断开")
			break
		}
		//打印客户端发送的数据
		fmt.Print("客户端发送的数据:", string(buf[:n])) //[:n]一定要写,否则会打印多余的东西出来
	}
}
func main() {
	fmt.Println("服务器开始监听...")
	//net.Listen("tcp", "0.0.0.0:8888")
	//1.tcp 表示使用网络协议是 tcp
	//2. 0.0.0.0 表示监听 8888 端口
	listener, err := net.Listen("tcp", "0.0.0.0:8888")
	if err != nil {
		fmt.Println("服务器监听失败:", err)
		return
	}
	defer listener.Close()

	for {
		// 等待客户端连接
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println("服务器接收客户端连接失败:", err)
			continue
		} else {
			fmt.Println("服务器接收客户端连接成功:", conn.RemoteAddr())
		}
		// 处理客户端请求
		//go handleClient(conn)
		go process(conn)
	}
}

2.2、运行结果查看

服务端运行

go run ../server/net1.go 
服务器开始监听...

再打开

go run client/net1.go 
hello test
客户端发送了11字节的数据,并退出

服务端输出

go run ../server/net1.go 
服务器开始监听...
服务器接收客户端连接成功: 127.0.0.1:63275
等待客户端发送数据...127.0.0.1:63275客户端发送的数据:hello test
等待客户端发送数据...127.0.0.1:63275客户端连接断开

3、只有当客户端输入 exit 的时候,客户端程序退出

3.1、服务端代码

package main

import (
	"fmt"
	"io"
	"net"
	"os"
)

func process(conn net.Conn) {
	// 处理客户端请求
	defer conn.Close() //关闭连接,如果不关闭会因为连接数不释放,导致服务器无法接收新的连接
	for {
		//创建新的切片
		buf := make([]byte, 1024)
		//读取客户端数据。如果客户端不 conn.Write(),conn.Read()会一直阻塞
		fmt.Printf("等待客户端发送数据...%v", conn.RemoteAddr())
		n, err := conn.Read(buf)

		if err == io.EOF {
			fmt.Println("客户端连接断开")
			break
		}
		if string(buf[:n]) == "exit\n" {
			fmt.Println("客户端请求退出")
			os.Exit(0)
		}
		//打印客户端发送的数据
		fmt.Print("客户端发送的数据:", string(buf[:n])) //[:n]一定要写,否则会打印多余的东西出来
	}
}
func main() {
	fmt.Println("服务器开始监听...")
	//net.Listen("tcp", "0.0.0.0:8888")
	//1.tcp 表示使用网络协议是 tcp
	//2. 0.0.0.0 表示监听 8888 端口
	listener, err := net.Listen("tcp", "0.0.0.0:8888")
	if err != nil {
		fmt.Println("服务器监听失败:", err)
		return
	}
	defer listener.Close()

	for {
		// 等待客户端连接
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println("服务器接收客户端连接失败:", err)
			continue
		} else {
			fmt.Println("服务器接收客户端连接成功:", conn.RemoteAddr())
		}
		// 处理客户端请求
		//go handleClient(conn)
		go process(conn)
	}
}

3.2、客户端代码

package main

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

func main() {
	conn, err := net.Dial("tcp", ":8888")
	if err != nil {
		fmt.Println("Error connecting to server:", err)
		return
	}
	//客户端可以发送单行数据到服务器,然后就退出
	reader := bufio.NewReader(os.Stdin) //os.Stdin是标准输入
	for {
		//从终端读取一行用户输入并准备发送给服务器
		line, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("Error reading input:", err)
		}
		//如果用户输入的是exit,则退出程序
		line = strings.Trim(line, " \r\n")
		if line == "exit" {
			fmt.Println("Exiting...")
			conn.Close()
			break
		}
		//再将line发送给服务器
		_, err = conn.Write([]byte(line + "\n"))
		if err != nil {
			fmt.Println("conn.Write err=", err)
		}

	}
}

3.3、运行结果查看

服务端运行

go run ../server/net1.go 
服务器开始监听...

再打开一个终端,运行客户端代码

go run net1.go 
hello
我这里可以测试连续 输入输出
我将要退出
exit
Exiting...

服务端输出

go run ../server/net1.go 
服务器开始监听...
服务器接收客户端连接成功: 127.0.0.1:53864
等待客户端发送数据...127.0.0.1:53864客户端发送的数据:hello
等待客户端发送数据...127.0.0.1:53864客户端发送的数据:我这里可以测试连输入输出
等待客户端发送数据...127.0.0.1:53864客户端发送的数据:我将要退出
等待客户端发送数据...127.0.0.1:53864客户端连接断开

http://www.kler.cn/a/387238.html

相关文章:

  • Nebula NGQL语言的使用 一
  • 云防护单节点2T抗攻击能力意味着什么?
  • [免费]SpringBoot+Vue3校园宿舍管理系统(优质版)【论文+源码+SQL脚本】
  • 灵活就业,真的等同于失业吗?“三无人员”如何齐短板获贷款
  • 招聘app开发,人才招聘、求职首要方式
  • 组件间通信(组件间传递数据)
  • lineageos-19 仓库群遍历,打印第一条git log
  • 【IEEE/EI会议】第八届先进电子材料、计算机与软件工程国际学术会议(AEMCSE 2025)
  • 初识TCP,实验加抓包带你理解为什么需要三次握手、四次挥手
  • 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-02
  • 高级java每日一道面试题-2024年10月30日-JVM篇-新生代垃圾回收器和老生代垃圾回收器有哪些?有什么区别?
  • ALU通常是双操作数结构
  • 数据库SQLite的使用
  • 在 CSS 中,gap 是 布局容器(flex 或 grid)的属性。它用于设置容器内子元素之间的间距。
  • D63【python 接口自动化学习】- python基础之数据库
  • 线性表(顺序表和链表)
  • C#入门 018 传值、输出、引用、数组、具名、可选参数、扩展方法(this)
  • 【Kafka:概念、架构与应用】
  • 【计算机视觉】深入浅出SLAM技术原理
  • 系统架构设计师论文:模型驱动架构设计方法及其应用
  • 【JAVA】Java基础—面向对象编程:类与对象-对象的创建
  • 【机器学习】28. 强化学习(Bellman, Q-learning, DQN, 优先级经验回放)
  • 【go从零单排】error错误处理及封装
  • 实操示例:通过AI不断优化论文大纲逻辑结构
  • 【学习笔记】SAP ABAP——数据类型
  • 自动化运维:提升效率与稳定性的关键技术实践