golang 简易聊天
client.go
------------------------------
package main import (
"net"
"fmt"
"bufio"
"echo/codec"
"time"
) var quitSemaphore chan bool func main() {
var tcpAddr *net.TCPAddr
tcpAddr,_=net.ResolveTCPAddr("tcp","127.0.0.1:9999")
conn,_:=net.DialTCP("tcp",nil,tcpAddr) //开启连接
defer conn.Close() //关闭连接
fmt.Println("Connected!")
go onMessageRecived(conn) //接收消息
go sendMessage(conn) //发送消息
<-quitSemaphore
} // 发送消息
func sendMessage(conn *net.TCPConn) {
//发送消息
for{
time.Sleep( * time.Second)
var msg string
fmt.Scanln(&msg)
if msg == "quit"{
quitSemaphore <- true
break
}
//lk
//b :=[]byte(msg +"\n")
//处理加密
b ,_ := codec.Encode(msg+"\n")
conn.Write(b)
}
}
server.go
-----------------------------
package main import (
"bufio"
"fmt"
"net"
"echo/codec"
) // 用来记录所有的客户端连接
var ConnMap map[string]*net.TCPConn func main() {
var tcpAddr *net.TCPAddr
ConnMap = make(map[string]*net.TCPConn) //初始化
tcpAddr,_=net.ResolveTCPAddr("tcp","127.0.0.1:9999") tcpListener,_:=net.ListenTCP("tcp",tcpAddr) //开启tcp 服务
//退出时关闭
defer tcpListener.Close()
for{
tcpConn,err :=tcpListener.AcceptTCP()
if err !=nil {
continue
}
fmt.Println("A client connected : "+ tcpConn.RemoteAddr().String())
// 新连接加入 map
ConnMap[tcpConn.RemoteAddr().String()] = tcpConn go tcpPipe(tcpConn)
}
}
//处理发送过来的消息
func tcpPipe(conn *net.TCPConn) {
ipStr :=conn.RemoteAddr().String()
defer func() {
fmt.Println("disconnected : "+ ipStr)
conn.Close()
}()
//读取数据
reader :=bufio.NewReader(conn)
for {
message ,err :=codec.Decode(reader)//reader.ReadString('\n')
if err != nil {
return
}
fmt.Println(string(message))
//这里返回消息改为广播
boradcastMessage(conn.RemoteAddr().String()+":"+string(message))
}
}
//广播给其它
func boradcastMessage(message string) {
//遍历所有客户端并发消息
for _,conn :=range ConnMap{
b,err :=codec.Encode(message)
if err != nil {
continue
}
conn.Write(b)
}
}
codec.go
------------------------
package codec import (
"bytes"
"encoding/binary"
"bufio"
) func Encode(message string) ([]byte, error) {
// 读取消息的长度
var length int32 = int32(len(message))
var pkg *bytes.Buffer = new(bytes.Buffer)
// 写入消息头
err := binary.Write(pkg, binary.LittleEndian, length)
if err != nil {
return nil, err
}
// 写入消息实体
err = binary.Write(pkg, binary.LittleEndian, []byte(message))
if err != nil {
return nil, err
} return pkg.Bytes(), nil
} func Decode(reader *bufio.Reader) (string, error) {
// 读取消息的长度
lengthByte, _ := reader.Peek()
lengthBuff := bytes.NewBuffer(lengthByte)
var length int32
err := binary.Read(lengthBuff, binary.LittleEndian, &length)
if err != nil {
return "", err
}
if int32(reader.Buffered()) < length+ {
return "", err
} // 读取消息真正的内容
pack := make([]byte, int(+length))
_, err = reader.Read(pack)
if err != nil {
return "", err
}
return string(pack[:]), nil
}
func onMessageRecived(conn *net.TCPConn) {
reader :=bufio.NewReader(conn)
for {
//解密
msg,err := codec.Decode(reader)//reader.ReadString('\n')
fmt.Println(msg)
if err !=nil {
quitSemaphore <- true
break
}
}
}
golang 简易聊天的更多相关文章
- php+websocket搭建简易聊天室实践
1.前言 公司游戏里面有个简单的聊天室,了解了之后才知道是node+websocket做的,想想php也来做个简单的聊天室.于是搜集各种资料看文档.找实例自己也写了个简单的聊天室. http连接分为短 ...
- RDIFramework.NET ━ .NET快速信息化系统开发框架 V2.8 版本━新增企业通(内部简易聊天工具)
RDIFramework.NET ━ .NET快速信息化系统开发框架 V2.8 版本 新增企业通(内部简易聊天工具) RDIFramework.NET,基于.NET的快速信息化系统开发.整合框架,给用 ...
- node.js+websocket实现简易聊天室
(文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) websocket提供了一种全双工客户端服务器的异步通信方法,这种通信方法使用ws或者wss协议,可 ...
- php_D3_“简易聊天室 ”实现的关键技术 详解
PHP+MySQL实现Internet上一个简易聊天室的关键技术 系统目标: 聊天室使用数据库汇集每个人的发言,并可将数据库内的发言信息显示在页面,让每个用户都可 ...
- Python开发【笔记】:aiohttp搭建简易聊天室
简易聊天室: 1.入口main.py import logging import jinja2 import aiohttp_jinja2 from aiohttp import web from a ...
- 学习JavaSE TCP/IP协议与搭建简易聊天室
一.TCP/IP协议 1.TCP/IP协议包括TCP.IP和UDP等 2.域名通过dns服务器转换为IP地址 3.局域网可以通过IP或者主机地址寻找到相应的主机 4.TCP是可靠的连接,效率低,且连接 ...
- 示例:Socket应用之简易聊天室
在实际应用中,Server总是在指定的端口上监听是否有Client请求,一旦监听到Client请求,Server就会启动一个线程来响应该请求,而Server本身在启动完线程之后马上又进入监听状态. 示 ...
- java+socket 简易聊天工具
1.服务器端程序 package com.test3; import java.io.*; import java.net.*; import java.awt.*; import java.awt. ...
- node+websocket创建简易聊天室
关于websocket的介绍太多,在这就不一一介绍了,本文主要实现通过websocket创建一个简易聊天室,就是90年代那种聊天室 服务端 1.安装ws模块,uuid模块,ws是websocket模块 ...
随机推荐
- Macbook Pro安装win7
1.进入OS X系统,在实用工具中打开Boot Camp助理 2.用磁盘工具对磁盘进行分区,将需要安装win7的分区格式化成FAT格式 3.用Boot Camp对磁盘进行分割,然后插入win7的安装光 ...
- ASP.NET 5探险(1):Azure中配置连接字符串、独立项目执行EF7数据迁移
(此文章同时发表在本人微信公众号“dotNET每日精华文章”,欢迎右边二维码来关注.) 题记:我开始把ASP.NET 5用于生产系统开发已经有1个多月了,也填了一些坑积累了一些经验,从今天开始会陆陆续 ...
- 机器学习公开课笔记(5):神经网络(Neural Network)——学习
这一章可能是Andrew Ng讲得最不清楚的一章,为什么这么说呢?这一章主要讲后向传播(Backpropagration, BP)算法,Ng花了一大半的时间在讲如何计算误差项$\delta$,如何计算 ...
- Windows系统上安装多个版本jdk,修改环境变量不生效
本机已经安装了jdk1.6,而比较早期的项目需要依赖jdk1.5,于是同时在本机安装了jdk1.5和jdk1.6. 安装jdk1.5前,执行 java -version 得到java version ...
- C++读取文件夹中所有的文件或者是特定后缀的文件
由于经常有读取一个文件夹中的很多随机编号的文件,很多时候需要读取某些特定格式的所有文件. 下面的代码可以读取指定文件家中的所有文件和文件夹中格式为jpg的文件 参考: http://www.2cto. ...
- BZOJ 1861: [Zjoi2006]Book 书架 splay
1861: [Zjoi2006]Book 书架 Description 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书 ...
- redis如何安装
http://www.redis.net.cn/download/ (1)下载,解压,编译: $ wget http://download.redis.io/releases/redis-3.0.6. ...
- Arduino101学习笔记(二)—— 一些注意的语法点
1.宏定义 2.整数常量 3.支持C++ String类 (1)String 方法 charAt() compareTo() concat() endsWith() equals() equalsIg ...
- Jmeter 分布式性能测试
作为一个纯 JAVA 的GUI应用,JMeter 对于CPU和内存的消耗还是很惊人的,所以当需要模拟数以千计的并发用户时,使用单台机器模拟所有的并发用户就有些力不从心,甚至还会引起JAVA内存溢出的错 ...
- hdu2546 01背包
http://acm.split.hdu.edu.cn/showproblem.php?pid=2546 01背包问题,首先拿出5元买最贵的东西,那接下来就是背包容量m-5,物品数量n-1 的01背包 ...