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

紧接着前面的章节,此篇,在tcp client端引入了锁、interfce、类的思想进去。

废话没有

tcp server端(跟上一篇一样)

 <span style="font-family: Arial, Helvetica, sans-serif;">package main</span><pre name="code" class="html">
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"
	"sync"
)

type message struct {
	data  string
	quit  chan int
	mutex *sync.Mutex
}

func (msg *message) send_msg(conn net.Conn) {

	for {
		fmt.Printf("client:")

		msg.mutex.Lock()
		msg.data = "" //输入发送的内容
		fmt.Scanln(&msg.data)
		send_buf := []byte(msg.data)
		msg.mutex.Unlock()

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

func (msg *message) recv_msg(conn net.Conn) {

	for !strings.EqualFold(msg.data, "Quit") { //收到Quit时退出
		recv_buf := make([]byte, 1024)
		lenght, err := conn.Read(recv_buf[0:]) //接受客户端数据
		if err != nil {
			break
		}
		msg.mutex.Lock() //这样加锁,其实不好的,因为for循环中还在用msg.data
		msg.data = ""
		msg.data = string(recv_buf[0:lenght]) //这里若不用leng,取到的data长度将会是1024
		fmt.Printf("\rserver:%s", msg.data)   //服务器发送的内容
		msg.mutex.Unlock()

		fmt.Printf("\rclient:")
	}
	conn.Close()
	msg.quit <- 0
	fmt.Println("server is disconnected")
}

func main() {

	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")

	msg := &message{data: "", quit: make(chan int), mutex: new(sync.Mutex)}
	go func() { msg.send_msg(conn) }()
	go func() { msg.recv_msg(conn) }()
	<-msg.quit
}




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值