GO语言实现多人聊天室

原创 2018年03月21日 15:54:36

运用go里面的net包中的相关方法来实现一个基于tcp的简单多人聊天室,用一个服务器来管理,主要反馈客户端是否连接成功并显示客户端输入的内容,并且发送给每一个在服务器上连接的客服端

服务器代码

// server
package main


import (
	"fmt"
	"net"
)


var ConnMap map[string]*net.TCPConn


func checkErr(err error) int {
	if err != nil {
		if err.Error() == "EOF" {
			fmt.Println("用户退出")
			return 0
		}
		fmt.Println("发生错误")
		return -1
	}
	return 1
}
func say(tcpConn *net.TCPConn) {
	for {
		data := make([]byte, 256)
		total, err := tcpConn.Read(data)
		if err != nil {
			fmt.Println(string(data[:total]), err)
		} else {
			fmt.Println(string(data[:total]))
		}


		flag := checkErr(err)
		if flag == 0 {
			break
		}
		for _, conn := range ConnMap {
			if conn.RemoteAddr().String() == tcpConn.RemoteAddr().String() {
				continue
			}
			conn.Write(data[:total])
		}
	}
}
func main() {
	//var conn net.TCPConn
	//localAddr :=conn.LocalAddr().String()
	//fmt.Println(localAddr)
	//tcpAddr, _ := net.ResolveTCPAddr("tcp",localAddr)
	tcpAddr, _ := net.ResolveTCPAddr("tcp", "192.168.128.216:8080")
	tcpListen, _ := net.ListenTCP("tcp", tcpAddr)
	ConnMap = make(map[string]*net.TCPConn)
	for {
		tcpConn, _ := tcpListen.AcceptTCP()
		defer tcpConn.Close()
		ConnMap[tcpConn.RemoteAddr().String()] = tcpConn
		fmt.Println("连接客户端信息:", tcpConn.RemoteAddr().String())


		go say(tcpConn)
	}
}

本来打算用系统的LocalAddr()函数来直接调用本地网络地址,但是这里调用一直报格式的错误,所以这里用本地地址直接输在里面,端口是8080//192.168.247.128:8080,也可以改成和客户端相似的代码来进行调用,但鉴于服务器唯一,所以就不做更改了

客户端代码

// client
package main


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


var ch chan int = make(chan int)
var nickname string


func reader(conn *net.TCPConn) {
	buff := make([]byte, 256)
	for {
		j, err := conn.Read(buff)
		if err != nil {
			ch <- 1
			break
		}
		fmt.Printf("%s\n", buff[0:j])
	}
}
func main() {
	if len(os.Args) != 2 {
		fmt.Fprintf(os.Stderr, "Usage:%s  host:port", os.Args[0])
		os.Exit(1)
	}
	service := os.Args[1]
	TcpAdd, _ := net.ResolveTCPAddr("tcp", service)
	//TcpAdd, _ := net.ResolveTCPAddr("tcp", "localhost:8080")
	conn, err := net.DialTCP("tcp", nil, TcpAdd)
	if err != nil {
		fmt.Println("服务没打开")
		os.Exit(1)
	}
	defer conn.Close()
	go reader(conn)
	fmt.Println("请输入昵称")
	fmt.Scanln(&nickname)
	fmt.Println("你的昵称是:", nickname)
	//var str string
	for {
		var msg string
		fmt.Scan(&msg)
		fmt.Print("<" + nickname + ">" + "说:")
		//for i, _ := range msg {
		//	fmt.Printf("%c", msg[i])
		//}
		fmt.Println(msg)
		b := []byte("<" + nickname + ">" + "说:" + msg)
		conn.Write(b)
		select {
		case <-ch:
			fmt.Println("server发生错误,请重新连接")
			os.Exit(2)
		default:
		}
	}
}

客户端主要就是向服务器发起连接,然后发送和接收数据,原计划定义一个字符切片来存储读来的数据,但是出现了调用fmt.Println()来输出是时候显示ASCII码的错误,所以改成直接往一个空字符串里面读写,然后再来调用fmt.Println(),显示出正确的字符串

运行服务器

go build server.go

./server

或  go run server.go

运行客户端

go build client.go

./client 服务器地址:端口(上面例子是192.168.247.128:8080)



版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shangguan_1234/article/details/79640856

Go语言最简单的tcp server/client

Go语言最简单的tcp server/client
  • shanshanpt
  • shanshanpt
  • 2016-11-08 14:02:49
  • 1608

Go语言中Tcp协议粘包问题处理

在用golang开发人工客服系统的时候碰到了粘包问题,那么什么是粘包呢?例如我们和客户端约定数据交互格式是一个json格式的字符串: {"Id":1,"Name":"golang","Message...
  • kenkao
  • kenkao
  • 2015-08-22 11:08:08
  • 7925

神奇的go语言(聊天室的开发)

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】    这是一篇关于聊天室开发的博客,原来文章的地址来自于此。这篇文章非常具有代表性,对于代码中...
  • feixiaoxing
  • feixiaoxing
  • 2014-07-21 23:10:32
  • 8140

基于c语言的多人聊天室系统

  • 2010年06月13日 17:34
  • 102KB
  • 下载

go语言安装第三方程序包

这里拿我最近正在看的一个源码举例。环境: win10+jetBrains Gogland+git bash客户端安装第三方go-cache程序包源码的地址https://github.com/patr...
  • pony_maggie
  • pony_maggie
  • 2017-08-13 20:00:01
  • 1102

golang tcp 客户端

最近找了网上tcp客户端的例子,都不是很好,特今天写一个tcp 客户端案例。 1.新建tcpclient结构体: type TcpClientModel struct { Conn...
  • niyuelin1990
  • niyuelin1990
  • 2017-09-06 17:27:29
  • 727

C语言基于socket多人聊天(包含注册登录)

  • 2013年08月08日 16:41
  • 7KB
  • 下载

TCP编程——实现多人聊天室功能

通过上一篇方法就能够实现TCP简单连接,但是有个问题,不能实现多客户端连接,因为服务器端如果接到一个连接请求之后,就会进入代码对应的循环中。那么怎么实现多人聊天呢? 实际上可以使用多线程,这样就不会...
  • u011680348
  • u011680348
  • 2016-01-08 16:25:52
  • 3697

使用golang快速开发微信公众平台(七):通过客服向用户发消息

注意:只能向与公众号24小时内发生过交互的用户发消息 公众平台向用户群发消息每个月是有次数限制的,而上述限制对非活跃用户其实并无特别大的影响。 发消息可以自己写字符串,也可以用模板,但是模板有诸多限制...
  • u012210379
  • u012210379
  • 2016-10-27 10:33:41
  • 808

Go语言(服务器开发):客户端向服务器发送数据并接收返回数据

客户端向服务器发送数据并接收返回数据。 示例代码:
  • books1958
  • books1958
  • 2014-09-24 18:26:04
  • 1640
收藏助手
不良信息举报
您举报文章:GO语言实现多人聊天室
举报原因:
原因补充:

(最多只允许输入30个字)