├── README ├── client └── client.go └── serverSocket.go /README: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "net" 5 | ) 6 | 7 | type Client struct { 8 | conn net.Conn 9 | } 10 | 11 | func (this *Client) quit() { 12 | this.conn.Close() 13 | } 14 | -------------------------------------------------------------------------------- /serverSocket.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | /** 4 | * 这是个简易的游戏服务器 5 | * 每条包结构会有个包头标志剩下的包体长度 6 | * 会进行断包粘包处理. 7 | * 每个客户端由一个Client实例来维护 8 | */ 9 | 10 | import ( 11 | "./client" 12 | "bufio" 13 | "encoding/binary" 14 | "fmt" 15 | "net" 16 | "os" 17 | "runtime" 18 | "strconv" 19 | ) 20 | 21 | const ( 22 | Head = 4 23 | ) 24 | 25 | var ( 26 | ClientMap map[int]net.Conn = make(map[int]net.Conn) 27 | Clients map[int]client.Client = make(map[int]client.Client) 28 | ) 29 | 30 | func main() { 31 | fmt.Println("CPU个数: ", runtime.NumCPU()) 32 | runtime.GOMAXPROCS(runtime.NumCPU()) 33 | fmt.Println(os.Args[0]) 34 | tcpAddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:7981") 35 | checkError(err) 36 | listener, err := net.ListenTCP("tcp", tcpAddr) 37 | checkError(err) 38 | clientIndex := 0 39 | 40 | for { 41 | conn, err := listener.Accept() 42 | if err != nil { 43 | fmt.Println("监听错误: ", err.Error()) 44 | continue 45 | } 46 | clientIndex++ 47 | go handleClient(conn, clientIndex) 48 | } 49 | } 50 | 51 | func handleClient(conn net.Conn, index int) { 52 | c := client.Client{conn} 53 | Clients[index] = c 54 | ClientMap[index] = conn 55 | fmt.Println("新用户连接, 来自: ", conn.RemoteAddr(), "index: ", index) 56 | sendMsgToAll("new user added, index: " + strconv.Itoa(index)) 57 | isHeadLoaded := false 58 | bodyLen := 0 59 | reader := bufio.NewReader(conn) 60 | 61 | defer func() { 62 | conn.Close() 63 | delete(ClientMap, index) 64 | fmt.Println("移除序号为: ", index, "的客户端") 65 | }() 66 | 67 | Out: 68 | for { 69 | if !isHeadLoaded { 70 | headLenSl := make([]byte, 4) 71 | fmt.Println("读取包头....") 72 | 73 | //已经读取的包头字节数 74 | readedHeadLen := 0 75 | 76 | for readedHeadLen < 4 { 77 | len, err := reader.Read(headLenSl) 78 | if err != nil { 79 | fmt.Println("读取包头出错, ", err.Error()) 80 | break Out 81 | } 82 | readedHeadLen += len 83 | } 84 | 85 | bodyLen = int(binary.BigEndian.Uint32(headLenSl)) 86 | fmt.Println("读取包头成功, 包体字节长度: ", bodyLen) 87 | isHeadLoaded = true 88 | } 89 | 90 | if isHeadLoaded { 91 | fmt.Println("解析包体") 92 | bodySl := make([]byte, bodyLen) 93 | 94 | //已经读取的包体字节数 95 | readedBodyLen := 0 96 | 97 | for readedBodyLen < bodyLen { 98 | len, err := reader.Read(bodySl) 99 | if err != nil { 100 | fmt.Println("读取包体出错,: ", err.Error()) 101 | break Out 102 | } 103 | readedBodyLen += len 104 | } 105 | 106 | fmt.Println("读取包体完成,包体字节长度: ", readedBodyLen) 107 | isHeadLoaded = false 108 | } 109 | } 110 | } 111 | 112 | func sendMsgToAll(msg string) { 113 | for _, value := range ClientMap { 114 | writer := bufio.NewWriter(value) 115 | msgLen := len(msg) 116 | //写入2个字节字符串长度.以供flash读取便利 117 | buf := make([]byte, 2) 118 | binary.BigEndian.PutUint16(buf, uint16(msgLen)) 119 | writer.Write(buf) 120 | writer.WriteString(msg) 121 | writer.Flush() 122 | } 123 | } 124 | 125 | func parseData(data []byte) { 126 | 127 | } 128 | 129 | func checkError(err error) { 130 | if err != nil { 131 | fmt.Println(err.Error()) 132 | os.Exit(1) 133 | } 134 | 135 | } 136 | --------------------------------------------------------------------------------