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模块 ...
随机推荐
- css 妙味 总结
技巧一: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF- ...
- windows7下安装php的imagick和imagemagick扩展教程
这篇文章主要介绍了windows7下安装php的imagick和imagemagick扩展教程,同样也适应XP操作系统,Win8下就没测试过了,需要的朋友可以参考下 最近的PHP项目中,需要用到切图和 ...
- WPF MVVM初体验
首先MVVM设计模式的结构, Views: 由Window/Page/UserControl等构成,通过DataBinding与ViewModels建立关联: ViewModels:由一组命令,可以绑 ...
- winedt打开.tex文件时会出现reading error,看不到任何文字
winedt打开.tex文件时会出现reading error,然后看不到任何文字. 解决办法:先打开空白的winedt,然后点击open,找到该.tex文件,将文件名右侧的 default 改为 ...
- LeetCode39/40/22/77/17/401/78/51/46/47/79 11道回溯题(Backtracking)
LeetCode 39 class Solution { public: void dfs(int dep, int maxDep, vector<int>& cand, int ...
- XML 文件解析
1.XML文件 <Data> <Movie id="1"> <title>good lucky to you</title> < ...
- 【SQL Sever】将SQL Sever中的一个数据表的数据导出为insert语句
例如:这SQL Sever中的一张数据表,想要将这张数据表中的数据 转化成一个一个的insert语句存储在txt的文档中,那么不论走到那里这个insert语句一执行,我们就能将这个数据表中的数据 ...
- ASP.NET中Url编码解码
今天遇到Url编码解码的问题,纠结了一天的时间,结果上网一查才发现太二了我们. 同事写的代码把url用HttpUtility.UrlEncode编码和解码了,本地测试没有问题,部署到服务器上就提示转码 ...
- CSS3 2D 转换
2D 转换 在本章中,您将学到如下 2D 转换方法: translate() rotate() scale() skew() matrix() 您将在下一章学习 3D 转换. 实例 div { tra ...
- 廖雪峰教程笔记:js中map和reduce的用法
举例说明,比如我们有一个函数f(x)=x2,要把这个函数作用在一个数组[1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map实现如下: 由于map()方法定义在JavaScript的 ...