public void Process(UDPPackageType pt, byte[] data) { if (_waitfor == pt) { TcpMapService.LogMessage("UDPServer:" + pt); if (pt == UDPPackageType.SessionConnect) { UDPConnectJson udpc = UDPConnectJson.Deserialize(Encoding.UTF8.GetString(data, 16, data.Length - 16)); if (udpc.token != this.ConnectToken) { _sl.RejectConnect(this); return; } byte[] buffprepair = UDPMeta.CreateSessionPrepair(SessionId, ConnectToken); SendToPeer(buffprepair); SendToPeer(buffprepair); _waitfor = UDPPackageType.SessionConfirm; return; } if (pt == UDPPackageType.SessionConfirm) { UDPConnectJson udpc = UDPConnectJson.Deserialize(Encoding.UTF8.GetString(data, 16, data.Length - 16)); if (udpc.token != this.ConnectToken) { _sl.RejectConnect(this); return; } byte[] buffready = UDPMeta.CreateSessionReady(SessionId, ConnectToken); SendToPeer(buffready); SendToPeer(buffready); _waitfor = UDPPackageType.SessionIdle; _reader = new BufferedReader(cts.Token); ThreadPool.QueueUserWorkItem(delegate { _sl._onstream(this, RemoteEndPoint); }); return; } if (pt == UDPPackageType.SessionIdle) { SendToPeer(UDPMeta.CreateSessionIdle(SessionId)); return; } } else { ProcessUDPPackage(pt, data); } }
void ListenerWorkThread() { while (this._workthread != null) { try { //TODO: if not cached , and all stream closed , shutdown directly IPEndPoint ep; byte[] data = _udp.Receive(TimeSpan.FromSeconds(90), out ep); if (data == null) { Console.WriteLine("_udp.Receive return null for a long time...; Shutdown..." + this._udp.LocalEndPoint); this.Close(); return; } UDPPackageType pt = UDPMeta.GetPackageType(data); if (pt == UDPPackageType.Unknown) { //Console.WriteLine("_udp.Receive return Unknown;"); return; } long sid = BitConverter.ToInt64(data, 8); ServerStream ss; //Console.WriteLine("_udp.Receive " + sid + ":" + pt); if (pt == UDPPackageType.SessionConnect) { UDPConnectJson udpc = UDPConnectJson.Deserialize(Encoding.UTF8.GetString(data, 16, data.Length - 16)); lock (strmap) { if (!strmap.TryGetValue(sid, out ss)) { ss = new ServerStream(this, sid, ep, udpc); strmap[sid] = ss; } } if (ss.ConnectToken != udpc.token) { ss.ForceClose(); lock (strmap) { ss = new ServerStream(this, sid, ep, udpc); strmap[sid] = ss; } } else { ss.Process(pt, data); } } else { lock (strmap) { strmap.TryGetValue(sid, out ss); } if (ss != null) { ss.Process(pt, data); } else { _udp.SendToClient(ep, UDPMeta.CreateSessionError(sid, "NotFound")); } } } catch (ThreadAbortException) { break; } catch (Exception x) { TcpMapService.OnError(x); } } }
void _Connect(UDPClientListener udp, string ip, int port, TimeSpan timeout) { _udp = udp; StartConnect: SessionId = Interlocked.Increment(ref _nextsessionid); string guid = Guid.NewGuid().ToString(); byte[] buffconnect = UDPMeta.CreateSessionConnect(SessionId, guid); SendToPeer(buffconnect); SendToPeer(buffconnect); while (true) { byte[] buffprepair = _udp.Receive(SessionId, TimeSpan.FromMilliseconds(500)); if (buffprepair == null) { CheckTimeout(timeout); Console.WriteLine("Client StartConnect Again"); //SendToPeer(buffconnect); SendToPeer(buffconnect); //continue; goto StartConnect; } UDPPackageType ptprepair = UDPMeta.GetPackageType(buffprepair); if (ptprepair != UDPPackageType.SessionPrepair) { if (ptprepair > UDPPackageType.SessionPrepair) { goto StartConnect; } continue; } long sidprepair = BitConverter.ToInt64(buffprepair, 8); if (sidprepair != SessionId) { goto StartConnect; } UDPConnectJson udpc = UDPConnectJson.Deserialize(Encoding.UTF8.GetString(buffprepair, 16, buffprepair.Length - 16)); if (udpc.token != guid) { goto StartConnect; } break; } byte[] buffconfirm = UDPMeta.CreateSessionConfirm(SessionId, guid); SendToPeer(buffconfirm); SendToPeer(buffconfirm); while (true) { byte[] buffready = _udp.Receive(SessionId, TimeSpan.FromMilliseconds(500)); if (buffready == null) { CheckTimeout(timeout); SendToPeer(buffconfirm); SendToPeer(buffconfirm); continue; } UDPPackageType ptprepair = UDPMeta.GetPackageType(buffready); if (ptprepair != UDPPackageType.SessionReady) { if (ptprepair > UDPPackageType.SessionReady) { goto StartConnect; } continue; } long sidprepair = BitConverter.ToInt64(buffready, 8); if (sidprepair != SessionId) { goto StartConnect; } UDPConnectJson udpc = UDPConnectJson.Deserialize(Encoding.UTF8.GetString(buffready, 16, buffready.Length - 16)); if (udpc.token != guid) { goto StartConnect; } break; } _reader = new ClientBufferReader(); Thread t = new Thread(ClientWorkThread); //TODO:Convert to async t.IsBackground = true; t.Start(); }