2 // HttpListener2Test.cs
3 // - Unit tests for System.Net.HttpListener - connection testing
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Collections.Generic;
32 using System.Globalization;
35 using System.Net.Sockets;
37 using System.Threading;
39 using NUnit.Framework;
41 // ***************************************************************************************
42 // NOTE: when adding prefixes, make then unique per test, as MS might take 'some time' to
43 // unregister it even after explicitly closing the listener.
44 // ***************************************************************************************
45 namespace MonoTests.System.Net {
49 [Ignore ("The class HttpListener is not supported")]
51 public class HttpListener2Test {
53 private HttpListener _listener = null;
55 public class MyNetworkStream : NetworkStream {
56 public MyNetworkStream (Socket sock) : base (sock, true)
60 public Socket GetSocket ()
66 public static HttpListener CreateAndStartListener (string prefix)
68 HttpListener listener = new HttpListener ();
69 listener.Prefixes.Add (prefix);
74 public static HttpListener CreateAndStartListener (string prefix, AuthenticationSchemes authSchemes)
76 HttpListener listener = new HttpListener ();
77 listener.AuthenticationSchemes = authSchemes;
78 listener.Prefixes.Add (prefix);
83 public static MyNetworkStream CreateNS (int port)
85 return CreateNS (port, 5000);
88 public static MyNetworkStream CreateNS (int port, int timeout_ms)
90 Socket sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
91 sock.Connect (new IPEndPoint (IPAddress.Loopback, port));
92 sock.SendTimeout = timeout_ms;
93 sock.ReceiveTimeout = timeout_ms;
94 return new MyNetworkStream (sock);
97 public static void Send (Stream stream, string str)
99 byte [] bytes = Encoding.ASCII.GetBytes (str);
100 stream.Write (bytes, 0, bytes.Length);
103 public static string Receive (Stream stream, int size)
105 byte [] bytes = new byte [size];
106 int nread = stream.Read (bytes, 0, size);
107 return Encoding.ASCII.GetString (bytes, 0, nread);
110 public static string ReceiveWithTimeout (Stream stream, int size, int timeout, out bool timed_out)
112 byte [] bytes = new byte [size];
113 IAsyncResult ares = stream.BeginRead (bytes, 0, size, null, null);
114 timed_out = !ares.AsyncWaitHandle.WaitOne (timeout, false);
117 int nread = stream.EndRead (ares);
118 return Encoding.ASCII.GetString (bytes, 0, nread);
121 public static HttpListenerContext GetContextWithTimeout (HttpListener listener, int timeout, out bool timed_out)
123 IAsyncResult ares = listener.BeginGetContext (null, null);
124 timed_out = !ares.AsyncWaitHandle.WaitOne (timeout, false);
127 return listener.EndGetContext (ares);
131 public void Dispose()
133 if (_listener != null) {
142 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test1/");
143 NetworkStream ns = CreateNS (9000);
144 Send (ns, "GET / HTTP/1.1\r\n\r\n"); // No host
145 string response = Receive (ns, 512);
147 Assert.IsTrue (response.StartsWith ("HTTP/1.1 400"));
153 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test2/");
154 NetworkStream ns = CreateNS (9000);
155 Send (ns, "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n"); // no prefix
156 string response = Receive (ns, 512);
158 Assert.IsTrue (response.StartsWith ("HTTP/1.1 400"));
164 StringBuilder bad = new StringBuilder ();
165 for (int i = 0; i < 33; i++){
167 bad.Append ((char) i);
187 foreach (char b in bad.ToString ()){
188 HttpListener listener = CreateAndStartListener ("http://127.0.0.1:9000/test3/");
189 NetworkStream ns = CreateNS (9000);
190 Send (ns, String.Format ("MA{0} / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n", b)); // bad method
192 string response = Receive (ns, 512);
195 Assert.AreEqual (true, response.StartsWith ("HTTP/1.1 400"), String.Format ("Failed on {0}", (int) b));
202 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test4/");
203 NetworkStream ns = CreateNS (9000);
204 Send (ns, "POST /test4/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n"); // length required
205 string response = Receive (ns, 512);
207 Assert.IsTrue (response.StartsWith ("HTTP/1.1 411"));
213 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test5/");
214 NetworkStream ns = CreateNS (9000);
215 Send (ns, "POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nTransfer-Encoding: pepe\r\n\r\n"); // not implemented
216 string response = Receive (ns, 512);
218 Assert.IsTrue (response.StartsWith ("HTTP/1.1 501"));
224 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test6/");
225 NetworkStream ns = CreateNS (9000);
226 // not implemented! This is against the RFC. Should be a bad request/length required
227 Send (ns, "POST /test6/ HTTP/1.1\r\nHost: 127.0.0.1\r\nTransfer-Encoding: identity\r\n\r\n");
228 string response = Receive (ns, 512);
230 Assert.IsTrue (response.StartsWith ("HTTP/1.1 501"));
236 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test7/");
237 NetworkStream ns = CreateNS (9000);
238 Send (ns, "POST /test7/ HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
239 HttpListenerContext ctx = _listener.GetContext ();
240 Send (ctx.Response.OutputStream, "%%%OK%%%");
241 ctx.Response.Close ();
242 string response = Receive (ns, 1024);
244 Assert.IsTrue (response.StartsWith ("HTTP/1.1 200"));
245 Assert.IsTrue (-1 != response.IndexOf ("Transfer-Encoding: chunked"));
251 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test8/");
252 NetworkStream ns = CreateNS (9000);
253 // Just like Test7, but 1.0
254 Send (ns, "POST /test8/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
255 HttpListenerContext ctx = _listener.GetContext ();
256 Send (ctx.Response.OutputStream, "%%%OK%%%");
257 ctx.Response.Close ();
258 string response = Receive (ns, 512);
260 Assert.IsTrue (response.StartsWith ("HTTP/1.1 200"));
261 Assert.IsTrue (-1 == response.IndexOf ("Transfer-Encoding: chunked"));
267 // 1.0 + "Transfer-Encoding: chunked"
268 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test9/");
269 NetworkStream ns = CreateNS (9000);
270 Send (ns, "POST /test9/ HTTP/1.0\r\nHost: 127.0.0.1\r\nTransfer-Encoding: chunked\r\n\r\n3\r\n123\r\n0\r\n\r\n");
272 string response = ReceiveWithTimeout (ns, 512, 1000, out timeout);
274 Assert.IsFalse (timeout);
275 Assert.IsTrue (response.StartsWith ("HTTP/1.1 411"));
279 public void Test10 ()
281 // Same as Test9, but now we shutdown the socket for sending.
282 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test10/");
283 MyNetworkStream ns = CreateNS (9000);
284 Send (ns, "POST /test10/ HTTP/1.0\r\nHost: 127.0.0.1\r\nTransfer-Encoding: chunked\r\n\r\n3\r\n123\r\n0\r\n\r\n");
285 ns.GetSocket ().Shutdown (SocketShutdown.Send);
287 string response = ReceiveWithTimeout (ns, 512, 1000, out timeout);
289 Assert.IsFalse (timeout);
290 Assert.IsTrue (response.StartsWith ("HTTP/1.1 411"));
294 public void Test11 ()
297 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test11/");
298 MyNetworkStream ns = CreateNS (9000);
299 Send (ns, "POST /test11/ HTTP/0.9\r\nHost: 127.0.0.1\r\n\r\n123");
300 ns.GetSocket ().Shutdown (SocketShutdown.Send);
301 string input = Receive (ns, 512);
303 Assert.IsTrue (input.StartsWith ("HTTP/1.1 400"));
307 public void Test12 ()
310 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test12/");
311 MyNetworkStream ns = CreateNS (9000);
312 Send (ns, "POST /test12/ HTTP/0.9\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
313 ns.GetSocket ().Shutdown (SocketShutdown.Send);
314 string input = Receive (ns, 512);
316 Assert.IsTrue (input.StartsWith ("HTTP/1.1 400"));
320 public void Test13 ()
323 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test13/");
324 MyNetworkStream ns = CreateNS (9000);
325 Send (ns, "GEt /test13/ HTTP/0.9\r\nHost: 127.0.0.1\r\n\r\n");
326 ns.GetSocket ().Shutdown (SocketShutdown.Send);
327 string input = Receive (ns, 512);
329 Assert.IsTrue (input.StartsWith ("HTTP/1.1 400"));
332 HttpListenerRequest test14_request;
333 ManualResetEvent test_evt;
336 public void Test14 ()
338 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test14/");
339 MyNetworkStream ns = CreateNS (9000);
340 Send (ns, "POST /test14/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
341 HttpListenerContext c = _listener.GetContext ();
342 test14_request = c.Request;
343 test_evt = new ManualResetEvent (false);
344 Thread thread = new Thread (ReadToEnd);
346 if (test_evt.WaitOne (3000, false) == false) {
349 Assert.IsTrue (false, "Timed out");
354 Assert.AreEqual ("123", read_to_end, "Did not get the expected input.");
360 using (StreamReader r = new StreamReader (test14_request.InputStream)) {
361 read_to_end = r.ReadToEnd ();
367 public void Test15 ()
369 // 2 separate writes -> 2 packets. Body size > 8kB
370 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test15/");
371 MyNetworkStream ns = CreateNS (9000);
372 Send (ns, "POST /test15/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 8888\r\n\r\n");
374 string data = new string ('a', 8888);
376 HttpListenerContext c = _listener.GetContext ();
377 HttpListenerRequest req = c.Request;
378 using (StreamReader r = new StreamReader (req.InputStream)) {
379 read_to_end = r.ReadToEnd ();
381 Assert.AreEqual (read_to_end.Length, data.Length, "Wrong length");
382 Assert.IsTrue (data == read_to_end, "Wrong data");
388 public void Test16 ()
390 // 1 single write with headers + body (size > 8kB)
391 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test16/");
392 MyNetworkStream ns = CreateNS (9000);
393 StringBuilder sb = new StringBuilder ();
394 sb.Append ("POST /test16/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 8888\r\n\r\n");
395 string eights = new string ('b', 8888);
397 string data = sb.ToString ();
399 HttpListenerContext c = _listener.GetContext ();
400 HttpListenerRequest req = c.Request;
401 using (StreamReader r = new StreamReader (req.InputStream)) {
402 read_to_end = r.ReadToEnd ();
404 Assert.AreEqual (read_to_end.Length, read_to_end.Length, "Wrong length");
405 Assert.IsTrue (eights == read_to_end, "Wrong data");
411 public void Test17 ()
413 _listener = CreateAndStartListener ("http://127.0.0.1:9000/test17/");
414 NetworkStream ns = CreateNS (9000);
415 Send (ns, "RANDOM /test17/ HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
416 HttpListenerContext ctx = _listener.GetContext ();
417 Send (ctx.Response.OutputStream, "%%%OK%%%");
418 ctx.Response.Close ();
419 string response = Receive (ns, 1024);
421 Assert.IsTrue (response.StartsWith ("HTTP/1.1 200"));
422 Assert.IsTrue (-1 != response.IndexOf ("Transfer-Encoding: chunked"));
426 public void Test_MultipleClosesOnOuputStreamAllowed ()
428 _listener = CreateAndStartListener ("http://127.0.0.1:9000/MultipleCloses/");
429 NetworkStream ns = CreateNS (9000);
430 Send (ns, "GET /MultipleCloses/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
432 HttpListenerContext ctx = _listener.GetContext ();
433 ctx.Response.OutputStream.Close ();
434 ctx.Response.OutputStream.Close ();
435 ctx.Response.OutputStream.Close ();
436 ctx.Response.Close ();
441 NetworkStream ns = CreateNS (9000);
442 Send (ns, "GET /SendCookie/ HTTP/1.1\r\nHost: 127.0.0.1\r\n"+
443 "Cookie:$Version=\"1\"; "+
444 "Cookie1=Value1; $Path=\"/\"; "+
445 "CookieM=ValueM; $Path=\"/p2\"; $Domain=\"test\"; $Port=\"99\";"+
446 "Cookie2=Value2; $Path=\"/foo\";"+
455 public void ReceiveCookiesFromClient ()
457 _listener = CreateAndStartListener ("http://127.0.0.1:9000/SendCookie/");
458 Thread clientThread = new Thread (new ThreadStart (SendCookie));
459 clientThread.Start ();
461 HttpListenerContext context = _listener.GetContext();
462 HttpListenerRequest request = context.Request;
464 Assert.AreEqual (3, request.Cookies.Count, "#1");
465 foreach (Cookie c in request.Cookies) {
466 if (c.Name == "Cookie1") {
467 Assert.AreEqual ("Value1", c.Value, "#2");
468 Assert.AreEqual ("\"/\"", c.Path, "#3");
469 Assert.AreEqual (0, c.Port.Length, "#4");
470 Assert.AreEqual (0, c.Domain.Length, "#5");
471 } else if (c.Name == "CookieM") {
472 Assert.AreEqual ("ValueM", c.Value, "#6");
473 Assert.AreEqual ("\"/p2\"", c.Path, "#7");
474 Assert.AreEqual ("\"99\"", c.Port, "#8");
475 Assert.AreEqual ("\"test\"", c.Domain, "#9");
476 } else if (c.Name == "Cookie2") {
477 Assert.AreEqual ("Value2", c.Value, "#10");
478 Assert.AreEqual ("\"/foo\"", c.Path, "#11");
479 Assert.AreEqual (0, c.Port.Length, "#12");
480 Assert.AreEqual (0, c.Domain.Length, "#13");
482 Assert.Fail ("Invalid cookie name " + c.Name);
486 private object _lock = new Object();
487 private string cookieResponse;
489 void ReceiveCookie () {
491 NetworkStream ns = CreateNS (9000);
492 Send (ns, "GET /ReceiveCookie/ HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n");
493 cookieResponse = Receive (ns, 512);
498 public void SendCookiestoClient ()
500 _listener = CreateAndStartListener ("http://127.0.0.1:9000/ReceiveCookie/");
501 Thread clientThread = new Thread (new ThreadStart (ReceiveCookie));
502 clientThread.Start ();
504 HttpListenerContext context = _listener.GetContext();
505 HttpListenerRequest request = context.Request;
506 HttpListenerResponse response = context.Response;
508 Cookie cookie = new Cookie ();
509 cookie.Name = "Name0";
510 cookie.Value = "Value0";
511 cookie.Domain = "blue";
512 cookie.Path = "/path/";
513 cookie.Port = "\"80\"";
515 response.Cookies.Add (cookie);
517 string responseString = "<HTML><BODY>----</BODY></HTML>";
518 byte[] buffer = Encoding.UTF8.GetBytes(responseString);
519 response.ContentLength64 = buffer.Length;
520 Stream output = response.OutputStream;
521 output.Write(buffer, 0, buffer.Length);
526 bool foundCookie = false;
527 foreach (String str in cookieResponse.Split ('\n')) {
528 if (!str.StartsWith ("Set-Cookie"))
530 Dictionary<string, String> dic = new Dictionary<string, String>();
531 foreach (String p in str.Substring (str.IndexOf (":") + 1).Split (';')) {
532 String[] parts = p.Split('=');
533 dic.Add (parts [0].Trim (), parts [1].Trim ());
535 Assert.AreEqual ("Value0", dic ["Name0"], "#1");
536 Assert.AreEqual ("blue", dic ["Domain"], "#2");
537 Assert.AreEqual ("\"/path/\"", dic ["Path"], "#3");
538 Assert.AreEqual ("\"80\"", dic ["Port"], "#4");
539 Assert.AreEqual ("1", dic ["Version"], "#5");
543 Assert.IsTrue (foundCookie, "#6");
548 public void MultiResponses ()
550 Thread srv = new Thread (new ThreadStart (EchoServer));
554 for (int i = 0; i < 10; i++) {
555 string payload = string.Format (CultureInfo.InvariantCulture,
558 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (
559 "http://localhost:8888/foobar/");
560 req.ServicePoint.Expect100Continue = false;
561 req.ServicePoint.UseNagleAlgorithm = false;
563 StreamWriter w = new StreamWriter (req.GetRequestStream ());
564 w.WriteLine (payload);
567 HttpWebResponse resp = (HttpWebResponse) req.GetResponse ();
568 StreamReader r = new StreamReader (resp.GetResponseStream ());
569 Assert.AreEqual ("Hello, " + payload + "!", r.ReadToEnd ().Trim ());
579 _listener = new HttpListener ();
580 _listener.Prefixes.Add ("http://*:8888/foobar/");
583 manualReset = new ManualResetEvent (false);
585 IAsyncResult result = _listener.BeginGetContext (
586 new AsyncCallback (EchoCallback), _listener);
587 manualReset.WaitOne ();
590 void EchoCallback (IAsyncResult result)
592 HttpListener listener = (HttpListener) result.AsyncState;
593 HttpListenerContext context = listener.EndGetContext (result);
594 HttpListenerRequest req = context.Request;
595 StreamReader r = new StreamReader (req.InputStream);
596 string reqBody = r.ReadToEnd ().Trim ();
598 HttpListenerResponse resp = context.Response;
599 StreamWriter o = new StreamWriter (resp.OutputStream);
600 o.WriteLine ("Hello, " + reqBody + "!");
603 listener.BeginGetContext (new AsyncCallback (EchoCallback), listener);
606 private ManualResetEvent manualReset;
611 public class HttpListenerBugs {
613 public void TestNonChunkedAsync ()
615 HttpListener listener = HttpListener2Test.CreateAndStartListener ("http://127.0.0.1:9123/");
617 listener.BeginGetContext (callback, listener);
619 HttpListener2Test.MyNetworkStream ns = HttpListener2Test.CreateNS (9123);
620 string message = "<script>\n"+
621 " <!-- register the blueprint for our show-headers service -->\n"+
622 " <action verb=\"POST\" path=\"/host/register\">\n" +
624 " <assembly>dream.tutorial.show-headers</assembly>\n" +
625 " <class>MindTouch.Dream.Tutorial.ShowHeadersService</class>\n" +
629 " <!-- instantiate it -->\n" +
630 " <action verb=\"POST\" path=\"/host/start\">\n" +
632 " <path>show-headers</path>\n" +
633 " <class>MindTouch.Dream.Tutorial.ShowHeadersService</class>\n" +
637 string s = String.Format ("POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: {0}\r\n\r\n{1}",
638 message.Length, message);
639 HttpListener2Test.Send (ns, s);
641 string response = HttpListener2Test.ReceiveWithTimeout (ns, 1024, 3000, out timedout);
644 Assert.IsFalse (timedout);
647 void callback (IAsyncResult ar)
649 HttpListener l = (HttpListener) ar.AsyncState;
651 HttpListenerContext c = l.EndGetContext (ar);
652 HttpListenerRequest request = c.Request;
654 StreamReader r = new StreamReader (request.InputStream);
655 string sr =r.ReadToEnd ();
656 HttpListener2Test.Send (c.Response.OutputStream, "Miguel is love");
661 // As it turns out, when we closed the OutputStream,
662 // we were not shutting down the connection, which was
663 // a documented pattern to close the connection
666 public void Test_MultipleConnections ()
668 HttpListener listener = HttpListener2Test.CreateAndStartListener ("http://127.0.0.1:9000/multiple/");
671 NetworkStream ns = HttpListener2Test.CreateNS (9000);
672 HttpListener2Test.Send (ns, "POST /multiple/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
673 HttpListenerContext ctx = listener.GetContext ();
674 HttpListener2Test.Send (ctx.Response.OutputStream, "%%%OK%%%");
675 ctx.Response.OutputStream.Close ();
676 string response = HttpListener2Test.Receive (ns, 1024);
680 ns = HttpListener2Test.CreateNS (9000);
681 HttpListener2Test.Send (ns, "POST /multiple/ HTTP/1.0\r\nHost: 127.0.0.1\r\nContent-Length: 3\r\n\r\n123");
682 ctx = listener.GetContext ();
683 HttpListener2Test.Send (ctx.Response.OutputStream, "%%%OK%%%");
684 ctx.Response.OutputStream.Close ();
685 response = HttpListener2Test.Receive (ns, 1024);
692 // Test case for bug 341443, an pretty old bug, filed on November of 2007.
695 public void Test_HostInUri ()
697 var wait = new ManualResetEvent (false);
698 var wait2 = new ManualResetEvent (false);
700 Thread t = new Thread (delegate (object a) {
703 NetworkStream ns = HttpListener2Test.CreateNS (9145);
704 HttpListener2Test.Send (ns, "GET http://www.google.com/ HTTP/1.1\r\nHost: www.google.com\r\nContent-Length: 3\r\n\r\n123456");
711 HttpListener listener = HttpListener2Test.CreateAndStartListener ("http://*:9145/");
713 HttpListenerContext ctx = listener.GetContext ();
715 Assert.AreEqual ("http://www.google.com:9145/", ctx.Request.Url.ToString ());
716 Assert.AreEqual ("http://www.google.com/", ctx.Request.RawUrl);
722 [Test] // bug #513849
723 public void ClosePort ()
725 var h = new HttpListener ();
726 h.Prefixes.Add ("http://127.0.0.1:8080/");
728 h.BeginGetContext (null, null);
730 TcpListener t = new TcpListener (IPAddress.Parse ("127.0.0.1"), 8080);