/// <summary> /// Tcp Listen thread /// </summary> private void ListenLoop(object o) { ManageListeningContext context = o as ManageListeningContext; Trace.WriteLine("Server listener started"); while (this.running) { TcpClient client = null; try { client = context.Listener.AcceptTcpClient(); } catch { Trace.TraceError("client side may disconnected"); return; } Trace.WriteLine(string.Format("Client {0} connected", (client.Client.RemoteEndPoint as IPEndPoint).ToString())); lock (context) { ManagedStream ms = new ManagedStream(); ms.LocalTcpClient = client; ms.PortInfo = context.PortInfo; ms.RemoteEndpoint = client.Client.RemoteEndPoint as IPEndPoint; Thread task = new Thread(new ParameterizedThreadStart(ReceiveLoop)); task.Start(ms); lock (clientStreams) { clientStreams.Add(ms); } context.ReceiveThreads.Add(task); } } }
/// <summary> /// Tcp Client thread /// </summary> /// <param name="o"></param> private void ReceiveLoop(object o) { ManagedStream ms = o as ManagedStream; TimeSpan idleTime = TimeSpan.FromMilliseconds(0); TimeSpan sleepTime = TimeSpan.FromMilliseconds(200); Stream s; HttpEndpointBase usedEndpoint = null; TcpClient c = ms.LocalTcpClient; // id it's using SSL, must authenticate self as server firstly if (ms.PortInfo.IsSSL) { SslStream ssl = new SslStream(c.GetStream(), true); try { ssl.AuthenticateAsServer(ms.PortInfo.ServerCertificate, false, System.Security.Authentication.SslProtocols.Tls, false); } catch (Exception e) { lock (eventPipe) { ManagedEvent exp = new ManagedEvent(); exp.EventType = EventType.Exception; exp.Exception = e; eventPipe.Enqueue(exp); return; } } s = ssl; } else { s = c.GetStream(); } ms.LocalStream = s; using (s) { while (this.running && idleTime < this.idleTimeout) { // if no data available, wait for a while if (c.Available == 0) { Thread.Sleep(sleepTime); idleTime += sleepTime; } // if data coming else { idleTime = TimeSpan.FromMilliseconds(0); byte[] data; // receive data using (var t = new MemoryStream()) { var buf = new byte[c.ReceiveBufferSize]; lock (ms) { do { var bytes = s.Read(buf, 0, buf.Length); t.Write(buf, 0, bytes); } while (c.Available > 0); ms.LastUsed = DateTime.Now; } data = t.ToArray(); } // pack as ManagedEvent var e = new ManagedEvent(); e.Data = data; e.Sender = c.Client.RemoteEndPoint as IPEndPoint; e.EventType = EventType.IncomingRequest; //parse the endpoint string str = Encoding.UTF8.GetString(data); e.Text = str; // try to parse as http try { HttpRequest req = new HttpRequest(); req.Parse(e.Text); e.ParsedHttpRequest = req; } catch { } if (usedEndpoint == null) { if (e.ParsedHttpRequest == null) { //first message is not http e.EventType = EventType.Exception; e.Exception = new Exception("The 1st request from this context is not an HTTP Request"); } else { lock (m_endpoints) { if (m_endpoints.ContainsKey(ms.PortInfo.Port)) { List <HttpEndpointBase> hebs = m_endpoints[ms.PortInfo.Port]; // find specific endpoint var q = from r in hebs where ( from u in r.Urls where e.ParsedHttpRequest.RequestUrl.Path.ToLower().Contains(u.ToLower()) select u ).Count() > 0 select r; // if found if (q.Any()) { e.ServiceEndpoint = (HttpEndpointBase)q.First(); usedEndpoint = e.ServiceEndpoint; } } } } } else { e.ServiceEndpoint = usedEndpoint; } // if service is auto-run, dispatch to its own pipe if (e.ServiceEndpoint != null && e.ServiceEndpoint.AutoRun) { lock (e.ServiceEndpoint.eventPipe) { e.ServiceEndpoint.eventPipe.Enqueue(e); } } else { lock (eventPipe) { eventPipe.Enqueue(e); } } } } } }