diff --git a/AddrServer/AddrServer.go b/AddrServer/AddrServer.go index e39c5fb..eb12daa 100644 --- a/AddrServer/AddrServer.go +++ b/AddrServer/AddrServer.go @@ -1,5 +1,6 @@ package main // 提供可用服务器地址的服务器 +// todo: 需要对地址池操作加访问锁 import ( "TCPServerClient/utils" @@ -26,19 +27,15 @@ type AddrServer struct { requestInfo string syncInfo string password string - addrs []CanBeUsedAddr // 可用服务器的地址 + addrs CanBeUsedAddrHeap // 可用服务器的地址池 + nextAddrIndex int // 用于服务器地址池取用 } // 开启server,并建立监听 -func (s *AddrServer) start() { +func (s *AddrServer) Start() { + // 初始化Server fmt.Println("Starting the addr server ...") - // 初始化 - s.serverIP= DefaultServerIP - s.serverPort= DefaultServerPort - s.authInfo=DefaultAuthenticationInfo - s.requestInfo=DefaultRequestInfo - s.password=DefaultPassword - s.syncInfo=DefaultSyncInfo + s.init() // 创建addrs清理协程 go s.verifyIPAddrList() @@ -57,17 +54,31 @@ func (s *AddrServer) start() { fmt.Println("Error accepting", err.Error()) return }else{ - fmt.Println("Main AddrServer Accept conn form "+conn.RemoteAddr().String()) + fmt.Println("AddrServer Accept conn form "+conn.RemoteAddr().String()) } // 处理请求 - go s.doMainServerStuff(conn) + go s.doAddrServerStuff(conn) } } +/** + 初始化 + */ +func (s *AddrServer) init() { + // 初始化 + s.serverIP= DefaultServerIP + s.serverPort= DefaultServerPort + s.authInfo=DefaultAuthenticationInfo + s.requestInfo=DefaultRequestInfo + s.password=DefaultPassword + s.syncInfo=DefaultSyncInfo + s.nextAddrIndex=0 +} + /** 处理TCP请求 */ -func (s *AddrServer) doMainServerStuff(conn net.Conn) { +func (s *AddrServer) doAddrServerStuff(conn net.Conn) { for { // 读取原始数据 buf := make([]byte, 512) @@ -83,7 +94,7 @@ func (s *AddrServer) doMainServerStuff(conn net.Conn) { msg=utils.DecryptMsgByDES(msg, s.password) fmt.Println("Received decrypt data: %v", msg) - // 判断是何种请求 + // 判断是何种请求,然后用不同的处理流程 if strings.HasPrefix(msg,s.authInfo) { s.doRequestStuff(conn,msg) }else if msg == s.syncInfo { @@ -112,39 +123,66 @@ func (s *AddrServer) doRequestStuff(conn net.Conn,msg string) { _ , err = conn.Write([]byte("true")) } - // 将该子网地址返回给客户端 - _ , err = conn.Write([]byte(s.addrs[0].ip)) + // 将可用服务器地址循环返回给客户端 + newAddr:=s.getCanBeUsedAddr() + _ , err = conn.Write([]byte(newAddr.ip)) if err != nil { fmt.Println("Error writing", err.Error()) }else{ fmt.Println("Send addr information to client successfully.") } + // 关闭本次连接 _ = conn.Close() } +// 取出地址池中下一个地址 +func (s *AddrServer) getCanBeUsedAddr() CanBeUsedAddr{ + if s.addrs.Len()>s.nextAddrIndex { + s.nextAddrIndex++ + return s.addrs[s.nextAddrIndex] + }else{ + s.nextAddrIndex=1 + return s.addrs[0] + } +} + /** 处理服务器请求:同步服务器地址 */ func (s *AddrServer) doSyncStuff(conn net.Conn) { - // 取出conn地址,更新到s.addr中 + // 取出conn地址 addrS := conn.RemoteAddr().String() cb:=CanBeUsedAddr{} cb.ip=strings.Split(addrS,":")[0] - s.addrs = append(s.addrs, cb) - fmt.Println("Added addr success : "+addrS) + // 检测是否已经存在该地址 + index := s.addrs.IsExistAddr(cb) + if index>=0 { + // 存在,则更新时间 + s.addrs[index].updateTime=time.Now() + fmt.Println("Updated addr success : "+addrS) + }else{ + // 不存在,则加入 + s.addrs = append(s.addrs, cb) + fmt.Println("Added addr success : "+addrS) + } + // 断开本次链接 _ = conn.Close() } /** - 定期清理不可连接的IP地址 + 定期清理不可连接的IP地址。主动清理,每10s。 */ func (s *AddrServer) verifyIPAddrList() { - fmt.Println("start addr cleaner...") + fmt.Println("start addr timeout cleaner...") + // 当系统当前时间-T_Update>=3600s时,将该IP地址及其后的IP地址全部移除IP池 for { for i := 0; i < len(s.addrs); i++ { - // todo:验证IP是否可用,不可用,则删掉 + if time.Now().Sub(s.addrs[i].updateTime)>=(time.Second*3600) { + s.addrs=s.addrs[:i] + } + break } - time.Sleep(time.Hour) + time.Sleep(time.Second*10) } } diff --git a/docs/~$N节点通过ADSL接入的方案.docx b/docs/~$N节点通过ADSL接入的方案.docx new file mode 100644 index 0000000..1f6da00 Binary files /dev/null and b/docs/~$N节点通过ADSL接入的方案.docx differ