代码不做注释了,因为我是把这个当作笔记来做的,如果感兴趣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]
}
服务端截图: