GO语言网络编程之TCP (v1)

本文介绍了作者在学习Go语言过程中,通过实现TCP服务器和客户端来加深理解。在服务器端,结合了channel、defer、range、routines、select和switch等概念,而客户端则保持简单。作者计划在后续文章中将面向对象思想应用到客户端。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近,将go语言的基础学习了一遍,感觉还得多练练才能拿得动这门语言;

        在TCP通信编程基础上,将一些杂七杂八的东西(channel/defer/range/routinue/select/switch)都添进去tcp server端,tcp client端还保留比较原始的部分;

        在下一篇中,计划将面向对象思想加到tcp client端。

        TCP基础就不介绍了,直接上代码,代码是有些问题,不妨碍知识点的应用和理解


tcp server端

package main

import (
	"fmt"
	"net"
	"strings"
	//	"time"
)

var exit_all = make(chan string)

func recv_msg(conn net.Conn, quit chan<- int) {
	defer func() {
		quit <- 0
	}()
	for {
		recv_buf := make([]byte, 1024)
		lenght, err := conn.Read(recv_buf) //接受客户端数据
		if err != nil {
			break
		}
		data := string(recv_buf[:lenght])

		if strings.EqualFold(data, "Quit") {
			break
		} else {
			fmt.Printf("\rclient:%s", data) //打印客户端发送的内容
			fmt.Printf("\rserver:")
		}

	}

}
func send_msg(conn net.Conn, quit chan<- int, exit chan<- int) {
	var data string //输入发送的内容
	defer func() {
		quit <- 0
		//	time.Sleep(1 * time.Second)
		exit <- 0
	}()
	for {
		data = ""
		fmt.Printf("server:")
		fmt.Scanln(&data)
		send_buf := []byte(data)
		if strings.EqualFold(data, "Exit") {
			break
		}
		_, err := conn.Write(send_buf) //向服务器发送数据
		if err != nil {
			fmt.Println(err)
			continue //发送出现错误,继续
		}
	}
}
func close_msg(conn net.Conn, quit <-chan int, exit <-chan int) {
	for {
		select { //此处仅仅为了用select而用
		case <-quit:
			conn.Close()
			fmt.Printf("\rclient is disconnected\n")
			fmt.Println("wait for connection...")
		case <-exit:
			exit_all <- "EXIT ALL"
		}
	}
}

func accept_conn(listener net.Listener) {
	for {
		conn, err := listener.Accept() //接受客户端请求
		if err != nil {
			fmt.Println(err)
			continue
		}
		fmt.Println("connect successfunlly!")

		quit, exit := make(chan int), make(chan int)
		go recv_msg(conn, quit)
		go send_msg(conn, quit, exit)
		go close_msg(conn, quit, exit)
	}
}

func main() {
	//监听端口
	listener, err := net.Listen("tcp", "localhost:7087")
	if err != nil {
		fmt.Println(err)
		return
	}
	go accept_conn(listener)
	for v := range exit_all {
		fmt.Println(v)
		break
	}
}

tcp client端

package main

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

func send_msg(conn net.Conn, quit chan int) {
	var data string //输入发送的内容

	for {
		data = ""
		fmt.Printf("client:")
		fmt.Scanln(&data)

		send_buf := []byte(data)
		_, err := conn.Write(send_buf) //向服务器发送数据
		if err != nil {
			fmt.Println(err)
			continue //发送出现错误,继续
		}
	}
}

func recv_msg(conn net.Conn, quit chan int) {
	var data string //收到的内容

	for !strings.EqualFold(data, "Quit") { //收到Quit时退出
		data = ""
		recv_buf := make([]byte, 1024)
		lenght, err := conn.Read(recv_buf[0:]) //接受客户端数据
		if err != nil {
			break
		}
		data = string(recv_buf[0:lenght]) //这里若不用leng,取到的data长度将会是1024

		fmt.Printf("\rserver:%s", data) //服务器发送的内容
		fmt.Printf("\rclient:")
	}
	conn.Close()
	quit <- 0
	fmt.Println("server is disconnected")
}

func main() {
	quit := make(chan int)

	conn, err := net.Dial("tcp", "127.0.0.1:7087") //连接服务器
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("If you want to exit,please input Quit")
	go send_msg(conn, quit) //发送消息
	go recv_msg(conn, quit) //接收消息
	<-quit
}<strong>
</strong>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值