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模块 ...
随机推荐
- C# 令某个窗体可跟着鼠标移动
/// <summary> /// 使窗口的中的指定控件支持运行时移动 /// TODO:运行时缩放 /// </summary> public class ControlMo ...
- android studio常见错误
1.Failed to import new Gradle project: Could not install Gradle distribution from'http://services.gr ...
- 避免在ASP.NET Core中使用服务定位器模式
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:服务定位器(Service Locator)作为一种反模式,一般情况下应该避免使用,在 ...
- x264 - 高品质 H.264 编码器
转自:http://www.5i01.cn/topicdetail.php?f=510&t=3735840&r=18&last=48592660 H.264 / MPEG-4 ...
- Java 对象序列化(Serialization Object)
官网文档:https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html 优秀博客: http://www.cnblogs.com/g ...
- 解决linux下unzip中文有乱码的问题
xxx.zip 中有中文的文件,在linux下unzip就会有乱码. 解决办法:安装7zip 去http://sourceforge.net/projects/p7zip/files/latest/d ...
- 在linux配置NFS用于RAC的搭建
rac的共享存储有很多种搭建方式,nfs是其中一种.生产环境一般不采用nfs,多用于测试. nfs搭建步骤大致分为如下: 1.划盘 给节点1挂载一块磁盘,并将磁盘分区,并格式化,再挂载 [root@n ...
- 2015最新移动App设计尺寸视觉规范【图文版】(转)
如今手机app的屏幕设计尺寸参差不齐,仿佛来到了移动界面尺寸战国时代,每家移动设备制造公司都为了迎合大众的口味,各家都在2014年大放光彩.2015年也将会是我们移动APP设计界快速发展的一年. 因为 ...
- AJAX案例二:简单表单验证
案例:如果用户名输入为张三,那么在失去焦点时后面会显示该用户名已被注册,否则显示可以注册! <%@ page language="java" import="jav ...
- Linux环境下搭建Tomcat+mysql+jdk
Linux环境 1.下载并安装一个VMware workstation, 这个是虚拟机的平台(自行度娘下载~),虚拟机是在后面要在里面搭建Linux系统. 2.下载一个centos安装包,linux版 ...