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, receiver, "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,"receiver":%d,"method":"%s","body":"%s"}`, sender, receiver, "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]
}

客户端截图:

服务端截图:

Go语言实现定向聊天,最简单的._第1张图片

你可能感兴趣的:(Golang)