Go语言实现定向聊天,最简单的.

代码不做注释了,因为我是把这个当作笔记来做的,如果感兴趣Go语言,加我QQ 我们一起学习这门新兴的语言.

服务端:Message_server.go

package main

import (
	"container/list"
	"encoding/json"
	"fmt"
	Json "go-json"  //go-simplejson
	"net"
	"sync"
	"time"
)

type Client_message struct {
	sender   int
	receiver int
	method   string
	body     string
}

type All_message struct {
	List *list.List
	Lock sync.Mutex
}

type Message struct {
	Time   int64
	Sender int
	Mes    string
}

var Ip_port string = ":5555"
var Message_map map[int]All_message = make(map[int]All_message)

func main() {
	Con,_ := net.Listen("tcp",Ip_port)
	defer Con.Close()
	for {
		con,_ := Con.Accept()
		fmt.Println(time.Now().Local(),":",con.RemoteAddr())
		go Connection(con)
	}
}
func Connection(con net.Conn) {
	defer con.Close()
	for {
		Buf := make([]byte,2048)
		n,e := con.Read(Buf)
		if e != nil {
			break
		}
		if n == 0 {
			continue
		}
		Mes,err := Json.NewJson(Buf[:n])
		if err != nil {
			con.Write([]byte("Not_Ok"))
			continue
		} else {
			con.Write([]byte("Ok"))
		}
		c_message := Convert_json(Mes)
		switch {
		case c_message.method == "put":
			Put_message(c_message)
		case c_message.method == "get":
			Buf := make([]byte,2048)
			list := Get_message(c_message.receiver)
			if list == nil {
				con.Write([]byte("0"))
				continue
			}
			Num := len(list)
			con.Write([]byte(fmt.Sprint(Num)))
			n,e := con.Read(Buf)
			checkError("get",e)
			if string(Buf[:n]) == "Get_len_ok" {
				for _,v := range list {
					n,e := con.Write(v)
					n,e = con.Read(Buf)
					checkError("get_for",e)
					if string(Buf[:n]) == "Get_ok" {
						continue
					} else {
						break
					}
				}
			}
		}
	}
}
func Put_message(C_message Client_message) {
	var String Message = Message{time.Now().Unix(),C_message.sender,C_message.body}
	if Message_map[C_message.receiver].List == nil {
		Message_map[C_message.receiver] = All_message{List: list.New()}
	}
	M := Message_map[C_message.receiver]
	M.Lock.Lock()
	M.List.PushFront(String)
	M.Lock.Unlock()
}

func Get_message(Num int) [][]byte {
	var message_list [][]byte
	if Message_map[Num].List == nil {
		return nil
	}
	L := Message_map[Num]
	L.Lock.Lock()
	x := L.List.Len()
	for i := 0; i < x; i++ {
		Date,_ := json.Marshal(L.List.Remove(L.List.Back()))
		message_list = append(message_list,Date)
	}
	L.Lock.Unlock()
	return message_list
}

func checkError(pos string,e error) {
	if e != nil {
		fmt.Println(pos," : ",e)
	}
}

func Convert_json(Mes *Json.Json) Client_message {
	var m Client_message
	method,_ := Mes.Get("method").String()
	sender,_ := Mes.Get("sender").Int()
	receiver,_ := Mes.Get("receiver").Int()
	body,_ := Mes.Get("body").String()
	m = Client_message{sender,receiver,method,body}
	return m
}
客户端:send_message.go

客户端我分为两个小部分,一个是专门自动接收的,一个是用的发消息的,我想两者同事进行,但不在GUI下面输入输出我不知道怎么解决,所以就搞成两部分.

package main

import (
	//"encoding/json"
	"fmt"
	json "go-json"
	"net"
	"strconv"
	t "time"
)

type Client_message struct {
	sender   int
	receiver int
	method   string
	body     string
}

type Message struct {
	Time   int64
	Sender int
	Mes    string
}

var sender int = 123456789
var receiver int = 1597805565 //QQ

func main() {
	con,err := net.Dial("tcp","127.0.0.1:5555")
	defer con.Close()
	if err != nil {
		fmt.Println(err)
	}
	/* 这个注销部分是用来发送消息的,编译的时候要注销掉这面一个for循环.
		for {
			var Str string
			fmt.Scan(&Str)
			if x := Send_message(con,Str); string(x) == "Ok" {
				fmt.Println("消息发送成功")
			}
		}
	*/
	for {  //这个for循环是用来接收消息的,不能和上面一个编译在一起.
		if e := Get_message(con); e != nil {
			break
		}
		t.Sleep(3e9)
	}

}

func Send_message(con net.Conn,Str string) []byte {
	mes := []byte(fmt.Sprintf(`{"sender":%d,"receiver":%d,"method":"%s","body":"%s"}`,sender,"put",Str))
	if 0 < len(mes) && len(mes) <= 2048 {
		Buf := make([]byte,2048)
		con.Write(mes)
		n,_ := con.Read(Buf)
		return Buf[:n]
	} else {
		fmt.Println("不能为空或者发送文本超过限制")
		return nil
	}
}
func Get_message(con net.Conn) error {
	var Buf []byte = make([]byte,2048)
	mes := []byte(fmt.Sprintf(`{"sender":%d,"get",""))
	_,e := con.Write(mes)
	if e != nil {
		fmt.Println("消息获取失败")
		return e
	}
	s := string(checkResponse(con))
	if s == "Ok" {
		Num,_ := strconv.Atoi(string(checkResponse(con)))
		if Num > 0 {
			con.Write([]byte("Get_len_ok"))
			for i := 0; i < Num; i++ {
				n,_ := con.Read(Buf)
				Result,_ := json.NewJson(Buf[:n])
				sender,_ := Result.Get("Sender").Int()
				time,_ := Result.Get("Time").Int64()
				body,_ := Result.Get("Mes").String()
				fmt.Println("发送人:",sender)
				fmt.Println("发送时间:",t.Unix(time,0).Format("2006-01-02 03:04:05 PM"),"内容:",body)
				con.Write([]byte("Get_ok"))
			}
		}
	}
	return nil
}

func checkResponse(con net.Conn) []byte {
	Buf := make([]byte,1024)
	n,e := con.Read(Buf)
	if e != nil {
		fmt.Println(e)
	}
	return Buf[:n]
}

客户端截图:

服务端截图:

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


类型转换 1、int转string 2、string转int 3、string转float 4、用户结构类型转换
package main import s &quot;strings&quot; import &quot;fmt&quot; var p = fmt.Println func main() { p(&quot;Contains: &quot;, s.Contains(&quot;test&quo
类使用:实现一个people中有一个sayhi的方法调用功能,代码如下: 接口使用:实现上面功能,代码如下:
html代码: beego代码:
1、读取文件信息: 2、读取文件夹下的所有文件: 3、写入文件信息 4、删除文件,成功返回true,失败返回false
配置环境:Windows7+推荐IDE:LiteIDEGO下载地址:http://www.golangtc.com/downloadBeego开发文档地址:http://beego.me/docs/intro/ 安装步骤: 一、GO环境安装 二、配置系统变量 三、Beego安装 一、GO环境安装 根
golang获取程序运行路径:
Golang的文档和社区资源:为什么它可以帮助开发人员快速上手?
Golang:AI 开发者的实用工具
Golang的标准库:为什么它可以大幅度提高开发效率?
Golang的部署和运维:如何将应用程序部署到生产环境中?
高性能AI开发:Golang的优势所在
本篇文章和大家了解一下go语言开发优雅得关闭协程的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。1.简介本文将介绍首先为什么需要主...
这篇文章主要介绍了Go关闭goroutine协程的方法,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。1.简介本文将介绍首先为什么需要主动关闭gor...
本篇文章和大家了解一下go关闭GracefulShutdown服务的几种方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。目录Shutdown方法Regi...
这篇文章主要介绍了Go语言如何实现LRU算法的核心思想和实现过程,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。GO实现Redis的LRU例子常
今天小编给大家分享的是Go简单实现多租户数据库隔离的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会...
这篇“Linux系统中怎么安装NSQ的Go语言客户端”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希
本文小编为大家详细介绍“怎么在Go语言中实现锁机制”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么在Go语言中实现锁机制”文章能帮助大家解决疑惑,下面...
今天小编给大家分享一下Go语言中interface类型怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考