并发聊天服务器
package mainimport ( "fmt" "net" "strings" "time"
)
type Client struct { C chan string Name string Addr string
}
var onlineMap map [ string ] Client
var message = make ( chan string ) func MakeMsg ( cli Client, msg string ) ( buf string ) { buf = "[" + cli. Addr + "]" + cli. Name + ": " + msgreturn
}
func WriteMsgToClient ( cli Client, conn net. Conn) { for msg := range cli. C { _ , err := conn. Write ( [ ] byte ( msg + "\n" ) ) if err != nil { fmt. Println ( "conn write err =" , err) return } }
}
func HandleConn ( conn net. Conn) { defer conn. Close ( ) cliAddr := conn. RemoteAddr ( ) . String ( ) cli := Client{ make ( chan string ) , cliAddr, cliAddr} onlineMap[ cliAddr] = cligo WriteMsgToClient ( cli, conn) message <- MakeMsg ( cli, "login" ) cli. C <- MakeMsg ( cli, "I am hello" ) isQuit := make ( chan bool ) isData := make ( chan bool ) go func ( ) { buf := make ( [ ] byte , 2048 ) for { readSize, err := conn. Read ( buf) if readSize == 0 { isQuit <- true fmt. Println ( "conn read err = " , err) return } msg := string ( buf[ : readSize- 1 ] ) if len ( msg) == 3 && msg == "who" { conn. Write ( [ ] byte ( "user list:\n" ) ) for _ , tmp := range onlineMap { msg = tmp. Addr + ":" + tmp. Name + "\n" conn. Write ( [ ] byte ( msg) ) } } else if len ( msg) >= 8 && msg[ : 6 ] == "rename" { name := strings. Split ( msg, "|" ) [ 1 ] cli. Name = nameonlineMap[ cliAddr] = cliconn. Write ( [ ] byte ( "rename ok\n" ) ) } else { fmt. Println ( "成朋" ) message <- MakeMsg ( cli, msg) } isData <- true } } ( ) for true { select { case <- isQuit: delete ( onlineMap, cliAddr) message <- MakeMsg ( cli, "login out" ) return case <- isData: case <- time. After ( 30 * time. Second) : delete ( onlineMap, cliAddr) message <- MakeMsg ( cli, "time out leave out" ) return } } }
func Manager ( ) { onlineMap = make ( map [ string ] Client) for true { meg := <- message for _ , client := range onlineMap { client. C <- meg } }
}
func main ( ) { listener, err := net. Listen ( "tcp" , ":8000" ) if err != nil { fmt. Println ( "listener err = " , err) return } defer listener. Close ( ) go Manager ( ) for true { conn, err := listener. Accept ( ) if err != nil { fmt. Println ( "conn err = " , err) continue } go HandleConn ( conn) }
}
调试工具netcat