//通过客户端的id请求,分配好服务端端口和appid交给客户端 //arrange ConfigId from top 4 bytes which received from client. //response: // 2 1 1 1 1 ...N // clientid appid port appid2 port2 //request: // 2 2 // clientid count // methodType value = 0 public byte[] ArrangeConfigIds(byte[] appRequestBytes, byte[] consumerPortBytes, int highPriorityClientId) { // byte[] arrangedBytes = new byte[256]; ClientModel clientModel = new ClientModel(); int clientId; //apprequestbytes里本身有clientId,但是如果传了highPriorityClientId,那就用这个clientId if (highPriorityClientId != 0) { clientId = highPriorityClientId; } else { clientId = StringUtil.DoubleBytesToInt(appRequestBytes[0], appRequestBytes[1]); } //2.分配clientid //TODO 这一段可能不会再用到了 int appCount = (int)appRequestBytes[2]; if (clientId == 0) { lock (_lockObject) { byte[] tempClientIdBytes = new byte[2]; //分配clientid for (int i = 0; i < 10000; i++) { _rand.NextBytes(tempClientIdBytes); int tempClientId = (tempClientIdBytes[0] << 8) + tempClientIdBytes[1]; if (!ServerContext.Clients.ContainsKey(tempClientId)) { clientModel.ClientId = tempClientId; clientId = tempClientId; break; } } } } else { clientModel.ClientId = clientId; } //注册客户端 ServerContext.Clients.RegisterNewClient(clientModel.ClientId); lock (_lockObject2) { //注册app clientModel.AppList = new List <App>(appCount); for (int i = 0; i < appCount; i++) { int startPort = StringUtil.DoubleBytesToInt(consumerPortBytes[2 * i], consumerPortBytes[2 * i + 1]); int arrangedAppid = ServerContext.Clients[clientId].RegisterNewApp(); //查找port的起始端口如果未指定,则设置为20000 //TODO 如果端口是指定的并且是绑定的,则直接使用该端口即可 if (startPort == 0) { startPort = 20000; } int port = NetworkUtil.FindOneAvailableTCPPort(startPort); NSPApp app = ServerContext.Clients[clientId].AppMap[arrangedAppid]; app.ClientId = clientId; app.AppId = arrangedAppid; app.ConsumePort = port; app.Tunnels = new List <TcpTunnel>(); app.ReverseClients = new List <TcpClient>(); ServerContext.PortAppMap[port] = app; clientModel.AppList.Add(new App { AppId = arrangedAppid, Port = port }); Logger.Info(port); //配置时触发 AppTcpClientMapConfigConnected(this, new AppChangedEventArgs() { App = app }); } Logger.Debug(" <=端口已分配。"); } return(clientModel.ToBytes()); }
/// <summary> /// 分配端口方法 /// arrange ConfigId from top 4 bytes which received from client. /// response: /// 2 1 1 1 1 ...N /// clientid appid port appid2 port2 /// request: /// 2 2 /// clientid count /// methodType value = 0 /// </summary> public byte[] ArrangeConfigIds(byte[] appRequestBytes, byte[] consumerPortBytes, int highPriorityClientId) { // byte[] arrangedBytes = new byte[256]; ClientModel clientModel = new ClientModel(); int clientId; //apprequestbytes里本身有clientId,但是如果传了highPriorityClientId,那就用这个clientId if (highPriorityClientId != 0) { clientId = highPriorityClientId; } else { clientId = StringUtil.DoubleBytesToInt(appRequestBytes[0], appRequestBytes[1]); } //2.分配clientid //TODO 这一段可能不会再用到了 int appCount = (int)appRequestBytes[2]; if (clientId == 0) { lock (_lockObject) { byte[] tempClientIdBytes = new byte[2]; //分配clientid for (int i = 0; i < 10000; i++) { _rand.NextBytes(tempClientIdBytes); int tempClientId = StringUtil.DoubleBytesToInt(tempClientIdBytes); if (!ServerContext.Clients.ContainsKey(tempClientId)) { clientModel.ClientId = tempClientId; clientId = tempClientId; break; } } } } else { clientModel.ClientId = clientId; } //注册客户端 ServerContext.Clients.RegisterNewClient(clientModel.ClientId); //port proto option(iscompress) host description //2 1 1 1024 96 int oneEndpointLength = 2 + 1 + 1 + 1024 + 96; lock (_lockObject2) { //注册app clientModel.AppList = new List <App>(appCount); for (int i = 0; i < appCount; i++) { int offset = oneEndpointLength * i; int startPort = StringUtil.DoubleBytesToInt(consumerPortBytes[offset], consumerPortBytes[offset + 1]); int arrangedAppid = ServerContext.Clients[clientId].RegisterNewApp(); Protocol protocol = (Protocol)consumerPortBytes[offset + 2]; bool isCompress = consumerPortBytes[offset + 3] == 1 ? true : false; string host = Encoding.ASCII.GetString(consumerPortBytes, offset + 4, 1024).TrimEnd('\0'); string description = Encoding.UTF8.GetString(consumerPortBytes, offset + 4 + 1024, 96).TrimEnd('\0'); //查找port的起始端口如果未指定,则设置为20000 if (startPort == 0) { startPort = Global.StartArrangedPort; } int port = 0; //如果端口是指定的并且是绑定的,不加任何检测 bool hasListened = false; if (IsBoundedByUser(clientId, startPort)) { port = startPort; } else { if (protocol == Protocol.TCP) { int relocatedPort = NetworkUtil.FindOneAvailableTCPPort(startPort); port = relocatedPort; //TODO 2 如果是共享端口协议,如果找不到端口则不进行侦听 } else if (protocol == Protocol.HTTP) { int relocatedPort = NetworkUtil.FindOneAvailableTCPPort(startPort); //兼容http侦听端口公用 if (port != relocatedPort) { //http协议下如果portappmap已经有值,说明已经发起过侦听,接下来不必再侦听 if (ServerContext.PortAppMap.ContainsKey(startPort)) { port = startPort; hasListened = true; } else { port = relocatedPort; } } } else if (protocol == Protocol.UDP) { int relocatedPort = NetworkUtil.FindOneAvailableUDPPort(startPort); port = relocatedPort; } } NSPApp app = ServerContext.Clients[clientId].AppMap[arrangedAppid]; app.ClientId = clientId; app.AppId = arrangedAppid; app.ConsumePort = port; app.AppProtocol = protocol; app.Host = host; app.Description = description; app.Tunnels = new List <TcpTunnel>(); app.ReverseClients = new List <TcpClient>(); app.IsCompress = isCompress; if (protocol == Protocol.UDP) { if (!ServerContext.UDPPortAppMap.ContainsKey(port)) { ServerContext.UDPPortAppMap[port] = new NSPAppGroup(); } ServerContext.UDPPortAppMap[port][host] = app; } else { //TODO 设置app的host和protocoltype(TCP Only) if (!ServerContext.PortAppMap.ContainsKey(port)) { ServerContext.PortAppMap[port] = new NSPAppGroup(); } ServerContext.PortAppMap[port][host] = app; } clientModel.AppList.Add(new App { AppId = arrangedAppid, Port = port }); Logger.Info(port); //配置时触发 if (!hasListened) { AppTcpClientMapConfigApplied(this, new AppChangedEventArgs() { App = app }); //触发listener侦听 } } Logger.Debug(" <=端口已分配。"); } return(clientModel.ToBytes()); }