伺服器端代碼:
package main
import (
"fmt"
"os"
"net"
"strings"
"log"
)
const LOG_DIRECTORY = "E:\\project\\mygo\\src\\chatRoom\\log.log"
var onlineConns = make(map[string]net.Conn)
var messageQueue = make(chan string, 1000)
var quitChan = make(chan bool)
var logger *log.Logger
func CheckError(err error) {
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
}
func ProcessInfo(conn net.Conn) {
buf := make([]byte, 1024)
defer func(conn net.Conn) {
addr := fmt.Sprintf("%s", conn.RemoteAddr())
delete(onlineConns, addr)
conn.Close()
for i := range onlineConns {
fmt.Println(i)
}
}(conn)
for {
numOfBytes, err := conn.Read(buf)
if err != nil {
continue
}
if numOfBytes != 0 {
message := string(buf[0:numOfBytes])
messageQueue <- message
//remoteAddr := conn.RemoteAddr()
//fmt.Println(remoteAddr)
//fmt.Printf("Has received this message:%s\n", string(buf[0:numOfBytes]))
}
}
}
func ConsumeMessage() {
for {
select {
case message := <- messageQueue:
//對消息進行解析
doProcessMessage(message)
case <- quitChan:
break
}
}
}
func doProcessMessage(message string) {
contents := strings.Split(message, "#")
if len(contents) > 1 {
addr := contents[0]
sendMessage := strings.Join(contents[1:], " ")
addr = strings.Trim(addr, " ")
if conn, ok := onlineConns[addr]; ok {
_, err := conn.Write([]byte(sendMessage))
if err != nil {
fmt.Println("消息發送失敗!")
}
}
}else {
contents := strings.Split(message, "*")
if strings.ToUpper(contents[1]) == "LIST" {
var ips string = ""
for i := range onlineConns{
ips = ips + "|" + i
}
if conn, ok := onlineConns[contents[0]]; ok {
_, err := conn.Write([]byte(ips))
if err != nil {
fmt.Println("消息發送失敗!")
}
}
}
}
}
func main() {
logFile, err := os.OpenFile(LOG_DIRECTORY, os.O_RDWR|os.O_CREATE, 0)
if err != nil {
fmt.Println("log File 建立失敗!")
os.Exit(-1)
}
defer logFile.Close()
logger = log.New(logFile, "\r\n", log.Ldate|log.Ltime|log.Llongfile)
listen_socket, err := net.Listen("tcp", "127.0.0.1:8900")
CheckError(err)
defer listen_socket.Close()
fmt.Println("聊天室已經開始運作!\n")
logger.Println("寫入日志!")
go ConsumeMessage()
for {
conn, err := listen_socket.Accept()
CheckError(err)
addr := fmt.Sprintf("%s", conn.RemoteAddr())
onlineConns[addr] =conn
for i := range onlineConns {
fmt.Println(i)
}
go ProcessInfo(conn)
}
}
用戶端代碼:
package main
import (
"os"
"net"
"fmt"
"bufio"
"strings"
)
func CheckError(err error) {
if err != nil {
fmt.Printf("s%", err)
os.Exit(1)
}
}
func MessageSend(conn net.Conn) {
var input string
for {
reader := bufio.NewReader(os.Stdin)
data, _ , _ := reader.ReadLine()
input = string(data)
//fmt.Println(strings.ToUpper(input))
if strings.ToUpper(input) == "EXIT" {
fmt.Println("關閉連接配接")
conn.Close()
break
}
_, err := conn.Write([]byte(input))
if err != nil {
conn.Close()
fmt.Println("用戶端連接配接錯誤:"+err.Error())
break
}
}
}
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:8900")
CheckError(err)
defer conn.Close()
//conn.Write([]byte("Hello Golang!"))
go MessageSend(conn)
buf := make([]byte, 1024)
for {
length, err := conn.Read(buf)
if err != nil {
fmt.Println("您已退出!")
os.Exit(0)
}
if length != 0 {
CheckError(err)
fmt.Println("收到消息,消息内容:"+ string(buf))
}
}
fmt.Print("消息已經發送!")
}