package main import ( "fmt" "net" "strings" "os" "log" ) // 服務器只是中轉! var msgQue = make(chan string, 1000) // 如今處理一個消息隊列 var quitChan = make(chan bool) // 管理退出消息 var onlineConns = make(map[string]net.Conn) // 管理鏈接 var logfile *os.File var logger *log.Logger 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("online"+i) } }(conn) for { numofbyte, err := conn.Read(buf) // 讀數據並賦值 if err != nil { break // 報錯退出 } if numofbyte != 0 { // 讀到了數據長度若是不等於0 msg := string(buf[:numofbyte]) //打印數據,注意以前發的數據由於改的是[]byte,存在未被覆蓋的字節信息,因此這裏切一下 msgQue <- msg // 這裏放到channel中 } } } func Checkerror1(err error) { if err != nil { panic(err) } } func doProcessMessage(mesa string){ content := strings.Split(mesa,"#") // 把字符串ip序號#消息進行分割 if len(content) >1 { //若是有消息 addr := content[0] sendMessage := strings.Join(content[1:],"#") // 這裏爲了防止消息中有另外的# if conn,ok := onlineConns[addr]; ok{ // 看是前面的ip否在消息隊列中 _, err := conn.Write([]byte(sendMessage)) //若是在的話寫入 if err != nil{ fmt.Println("wrong") } } } } func ConsumeMessage() { // 這個consume用select用來監控兩個channel若是quitchan有消息就退出,若是不是就處理消息進行分發 for { select { case mssage := <-msgQue: //解析 doProcessMessage(mssage) // 消息處理,並進行分發 case <-quitChan: break } } } func main() { logfile, err := os.OpenFile("LOG_DIRECORY", os.O_RDWR|os.O_CREATE,0) // 打開文件 if err != nil{ fmt.Println("log file create failure!") os.Exit(-1) } defer logfile.Close() logger = log.New(logfile,"\r\n",log.Ldate|log.Ltime|log.Llongfile) logger.Println("llkjklj") // 輸入log listen_s, err := net.Listen("tcp", "127.0.0.1:8080") // 開啓一個socket Checkerror1(err) defer listen_s.Close() // 結束關socket fmt.Println("server is waiting..") go ConsumeMessage() for { conn, err := listen_s.Accept() // socket 接連接 Checkerror1(err) addr := fmt.Sprintf("%s",conn.RemoteAddr()) // 把這個轉換一下到string中 onlineConns[addr] = conn go ProcessInfo(conn) // 處理數據 } }
package main import ( "fmt" "net" "bufio" "os" "strings" ) func MessageSend(conn net.Conn) { var input string for { reader := bufio.NewReader(os.Stdin) // 標準輸入 data, _,_ := reader.ReadLine() // 讀到數據到data input = string(data) if strings.ToUpper(input) == "EXIT" { // 若是寫的是exit就退出 conn.Close() break } _, err := conn.Write([]byte(input)) // 發消息 if err != nil { // 報錯退出 conn.Close() fmt.Println("Clinet connect fail") break } } } func Checkerror( err error){ if err != nil { panic(err) } } func main(){ conn, err := net.Dial("tcp","127.0.0.1:8080") // 鏈接socket Checkerror(err) defer conn.Close() MessageSend(conn) // 發消息 buf := make([]byte,1024) for { _, err := conn.Read(buf) // 讀消息 if err != nil{ fmt.Println("exit") os.Exit(0) // 正常退出 } fmt.Println(string(buf)) } }