golang 实现 tcp-聊天室

本文档介绍了如何使用Golang的net包实现一个TCP聊天室应用。文章详细阐述了goroutine和channel的概念,并提供了代码示例。通过goroutine处理用户交互,利用channel进行消息传递和广播。此外,还讲解了聊天室模型、用户模型和服务器模型的构建,以及用户、聊天室和服务器之间的交互过程。

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

golang 实现 tcp-聊天室

以下代码都已传到github平台:https://github.com/ElzatAhmed/go-tcp-chatroom

想必做golang网络开发的同学对gosdk中net/http包十分熟悉,使用net/http可以快速实现http服务器的搭建。但是大家对tcp协议的直接使用可能就没有那么熟悉了。在接下来的文档里我将讲解如何使用gosdk中的net包实现一个以tcp协议为基础的简易的终端群聊聊天室应用。
在dive in之前,需要回顾/介绍以下golang并发编程中的核心概念:

goroutine

在go.dev中是这么介绍goroutine的 A goroutine is a lightweight thread managed by the Go runtime,goroutine是一种被go runtime管理的轻量级线程,其并不会直接对应到重量级的系统线程上,而是被go scheduler调度到少量的系统线程上进行维护。所以在一个go程序中,我们可以同时创造成千上万个goroutine,将其交给go runtime去进行调度和垃圾回收。

channel

不知道你是否听说过一种理论叫做CSP,Communicating Sequential Processes,go将其核心思想总结成以下 Do not communicate by sharing memory, share memory by communicating,也就是说不要利用共享内存的方式去交互,利用交互的方式去共享内存(这里的交互这一名词可能用得不太对,大家可以以communication去理解)。channel正是利用这种思想而定义的。channel可以被理解为支持写入和读取的消息管道,其是完全并发安全,channel的每一个元操作都是以单线程的方式进行的,这就代表我们不仅能利用channel进行线程间通信,我们还可以利用它实现锁。以下是一种利用buffered channel (size大于0的channel) 实现的结构非常简单的锁:

package chlock

// Chlock is a locker implemented using channel
type Chlock struct {
   
	ch chan interface{
   }
}

// New returns the pointer to a new Chlock struct
func New() *Chlock {
   
	return &Chlock{
   
		ch: make(chan interface{
   }, 1),
	}
}

// Lock writes once to the channel and
// blocks all the other goroutines which tries to write
func (lock *Chlock) Lock() {
   
	lock.ch <- struct{
   }{
   }
}

// Unlock reads from the channel and unblock one goroutine
func (lock *Chlock) Unlock() {
   
	<-lock.ch
}

创建1000个goroutine对同一个全局变量count进行加一操作去测试我们实现的ChLock是否有效:

package main

import (
	"fmt"
	"sync"

	"github.com/elzatahmed/channel-lock/chlock"
)

var count int

func main() {
   
	var wg sync.WaitGroup
	wg.Add(1000)
	lock := chlock.New()
	for i := 0; i < 1000; i++ {
   
		go add(lock, &wg)
	}
	wg.Wait()
	fmt.Printf("count = %d\n", count)
}

func add(lock *chlock.Chlock, wg *sync.WaitGroup) {
   
	lock.Lock()
	defer wg.Done()
	defer lock.Unlock()
	count++
}

输出:

➜  channel-lock go run main.go
count = 1000

介绍完goroutine和channel之后我们就dive in到实现tcp聊天室的过程当中:

tcp聊天室的实现

首先我们开始打造聊天室的模型基础:

模型

第一个模型即用户模型,我们简单的以用户的名字作为用户的主键,并为其创建两个channel:

  1. receive channel:即获取消息的channel
  2. done channel:发送/获取断开连接的channel
// user is a single connection to the tcp chat server
type user struct {
   
	name    string
	receive chan message
	done    chan interface{
   
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值