【GO语言】实现TCP—CS设计模式的服务器server端与客户client端【并发】通信

【GO语言】实现TCP—CS设计模式的服务器server端与客户client端【并发】通信,第1张

GO语言实现TCP—C/S设计模式的服务器server端与客户client端【并发】通信 项目总览:一、项目开发日志二、图解并发服务器三、服务器端代码展示四、客户端代码展示五、效果展示:

项目总览:

1.开发语言:GO语言
2.IDE:Goland
3.开发用时:一个小时
4.源码已上传到我的GitHub,链接:https://github.com/2394799692/TCP-C-S 或点此跳转
5.基础知识请参考上一篇文章:【GO语言】实现TCP—C/S设计模式的服务器server端与客户client端即时通信


以下是本篇文章正文内容,欢迎朋友们进行指正,一起探讨,共同进步。——来自考研路上的lwj。QQ:2394799692

一、项目开发日志
服务器开发日志:
1.创建 监听套接字 listener:=net.listen("tcp",服务器的IP+PORT)  注意:tcp不能大写
2.defer listenerclose() 关闭
3.for 循环阻塞监听客户端连接事件 conn:=listener.Accept()
4.创建go程 对应每一个客户端进行数据通信  go HandlerConnet()
5.实现HandlerConnet
1)defer conn.close()
2)获取成功连接的客户端地址  conn.remoteaddr()
3)for循环读取客户端发送数据 conn.read(buf)
4)处理数据:小写转为大写    strings.toupper()
5)回写转化后的数据         conn.write(buf[:n])

服务器判断关闭:
read读客户端,返回0——对端关闭
nc命令发送数据时,默认在结尾自带“\n”

二、图解并发服务器

三、服务器端代码展示
package main

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

func HandlerConnect(conn net.Conn) {
	defer conn.Close()
	//获取连接的客户端 addr
	addr := conn.RemoteAddr()
	fmt.Println(addr, "客户端成功连接!")
	//循环读取客户端发送数据
	buf := make([]byte, 4096)
	for {
		n, err := conn.Read(buf)
		if "exit\n" == string(buf[:n]) || "exit\r\n" == string(buf[:n]) {
			fmt.Println("服务器接收到客户端的退出请求,断开连接!!!")
			return
		}
		if n == 0 {
			fmt.Println("服务器检测到客户端关闭,断开连接!!!")
			return
		}
		if err != nil {
			fmt.Println("conn.Read err:", err)
			return
		}
		fmt.Println("服务器读到数据:", string(buf[:n])) //使用数据
		//小写转大写,回发给客户端
		conn.Write([]byte(strings.ToUpper(string(buf[:n]))))
	}
}
func main() {
	//创建监听套接字
	listener, err := net.Listen("tcp", "127.0.0.1:8001") //本地回环地址,可先用ipconfig命令查看本机ip然后修改为局域网ip
	if err != nil {
		fmt.Println("net.listen err:", err)
		return
	}
	defer listener.Close()
	//监听客户端连接请求
	for {
		fmt.Println("服务器等待客户端连接..+.")
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println("listener.Accept err:", err)
			return
		}
		//具体完成服务器和客户端的数据通信
		go HandlerConnect(conn)
	}

}


四、客户端代码展示
package main

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

func main() {
	//主动发起连接请求
	conn, err := net.Dial("tcp", "127.0.0.1:8001")
	if err != nil {
		fmt.Println("net.dial err:", err)
		return
	}
	defer conn.Close()
	//获取用户的键盘输入,将输入数据发送给服务器
	go func() {
		str := make([]byte, 4096)
		for {
			n, err := os.Stdin.Read(str)
			if err != nil {
				fmt.Println("os.Stdin.Read err:", err)
				continue
			}
			//写给服务器,读多少,写多少
			conn.Write(str[:n])
		}
	}()
	//回显服务器回发的大写数据
	buf := make([]byte, 4096)
	for {
		n, err := conn.Read(buf)
		if n == 0 {
			fmt.Println("检测到服务器关闭,客户端也关闭")
			return
		}
		if err != nil {
			fmt.Println("conn.Read err:", err)
			return
		}
		fmt.Println("客户端读到服务器回发:", string(buf[:n]))
	}
}



五、效果展示:

1)启动服务器端,显示等待客户端建立连接:

2)运行并发服务器客户端(到根目录下打开cmd输入go run 04-TCP-CS并发客户端.go):

3)再打开几个客户端,同时连接服务器:


4)实现并发数据传输

5)当检测到客户端输入exit或关闭窗口时,结束服务并断开连接

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/995325.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存