client 端代码
package main import ( "fmt" "bufio" "net" "os" "strings" ) // 错误处理 func CheckError(err error) { if err !=nil{ panic(err) } } func MessageSend(conn net.Conn) { var input string for { // 从终端获取标准输入Stdin (standard input) reader:=bufio.NewReader(os.Stdin) // 保存终端输入信息 data,_,_ :=reader.ReadLine(); // 将byte转换成string input = string(data) // 判断终端是否输入退出命令 if strings.ToLower(input)=="exit" { conn.Close() break } // 向服务器写入数据 _,err:=conn.Write([]byte(input)) // 发生错误时退出 if err != nil { conn.Close() fmt.Println("client connect failure " + err.Error()) break } } } // 主函数 func main() { // 采用tcp协议主动向127.0.0.1的8080端口发起交互 conn,err := net.Dial("tcp","127.0.0.1:8080") CheckError(err) defer conn.Close() // 发送数据方法 go MessageSend(conn) // 申明一个缓存变量 buff :=make([]byte ,1024) // 无限监控服务端发送过来的信息 for{ // 读取服务端返回数据 _ ,err :=conn.Read(buff) // 如果读取数据时发生错误则退出系统 if err != nil { fmt.Println("你已经退出,欢迎下次再次使用!") os.Exit(0) } // 正常运行时打印出接收服务器端发送过来是信息 fmt.Println("receive server message content:" + string(buff)) } fmt.Println("client program end!") }
server端代码 package main import ( "os" "fmt" "net" "strings" "log" ) // 申明一个日志文件变量 var logFile *os.File var logger *log.Logger; // 申明一个变量,用于存储在线的客户端连接 var onlineConns = make(map[string]net.Conn) var messageQueue = make(chan string,1000) var quitChan = make(chan bool) const ( LOG_DIRECTORY = "./test.log" ) func CheckError(err error) { if err !=nil { fmt.Println("Error :%s",err.Error()) os.Exit(1) } } func ProcessInfo(conn net.Conn) { buf := make([]byte,1024) defer func(conn2 net.Conn) { addr :=fmt.Sprintf("%s",conn2.RemoteAddr()) delete(onlineConns,addr) conn.Close() for address := range onlineConns{ fmt.Println("now online conns :" + address) } }(conn) for { numOfBytes,err := conn.Read(buf) if err !=nil{ break } if numOfBytes !=0 { message := string(buf[0:numOfBytes]) messageQueue <- message } } } func comsumMessage() { 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:],"#") if conn,ok := onlineConns[addr] ;ok{ _,err := conn.Write([]byte(sendMessage)) if err != nil{ fmt.Println("online is failure") } } }else { contents := strings.Split(message,"*") if strings.ToLower(contents[1]) =="list"{ var ips string = ""; for address := range onlineConns{ ips = ips + "|" + address } if conn,ok := onlineConns[contents[0]] ;ok{ _,err := conn.Write([]byte(ips)) if err != nil{ fmt.Println("online is failure") } } } } } func main() { logFile ,err := os.OpenFile(LOG_DIRECTORY,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) listen_socket ,err := net.Listen("tcp","127.0.0.1:8080") CheckError(err) defer listen_socket.Close() fmt.Println("server is waitting......") logger.Println("I am writing the logs ") go comsumMessage() for { conn,err := listen_socket.Accept() CheckError(err) // 将conn.RemoteAddr() 存储到addr变量中 addr :=fmt.Sprintf("%s",conn.RemoteAddr()) onlineConns[addr]=conn for address := range onlineConns{ fmt.Println(address) } go ProcessInfo(conn) } }