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

前端之家收集整理的这篇文章主要介绍了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]
}

客户端截图:

服务端截图:

原文链接:https://www.f2er.com/go/190358.html

猜你在找的Go相关文章