最近实现一套简单的网络程序。为了查看程序内部的变量,方便调试。就在想搞一个最最简单的方式。第一个想到写文件,日志。这个不实时,而且打开麻烦,pass 。于是想到用网络输出。本来是想写成c/s模式,想着写client端也麻烦。
就不能用浏览器吗?于是想起,http协议。
http协议,是基于文本的网络传输协议,协议简单。在这里,忽略请求内容。不管浏览器请求什么内容,服务器都输出我的变量内容。只要一个页面,不需要考虑其它,只要能显示。
那就开始上代码:
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace HttpTest { class HttpServer { private bool _isRunning; private readonly int _port; private TcpListener _tcpListener; public HttpServer(int port) { _port = port; } public void Run() { _isRunning = true; _tcpListener = new TcpListener(IPAddress.Any, _port); _tcpListener.Start(); while (_isRunning) { TcpClient client; try { client = _tcpListener.AcceptTcpClient(); } catch (Exception ex) { Console.WriteLine(ex.Message); break; } Thread thread = new Thread(StartNewConnection); thread.IsBackground = true; thread.Start(client); } } public void Stop() { _isRunning = false; try { _tcpListener.Stop(); } catch { } } private void StartNewConnection(object obj) { TcpClient client = (TcpClient)obj; NetworkStream stream = client.GetStream(); const int bufferLength = 10240; byte[] buffer = new byte[bufferLength]; //管它是什么,没有解析http请求。 stream.Read(buffer, 0, bufferLength); byte[] content = GetContent(); stream.Write(content, 0, content.Length); stream.Flush(); client.Close();//简单处理,关了。 } private byte[] GetContent() { StringBuilder http = new StringBuilder(); http.AppendLine("HTTP/1.0 200 OK");//这些字,就代表了是http协议。 http.AppendLine("Content-type:text/html"); http.AppendLine("Connection:close"); StringBuilder html = new StringBuilder(); html.AppendLine("<html>"); html.AppendLine("<head>"); html.AppendLine("<title>hello</title>"); html.AppendLine("</head>"); html.AppendLine("<body>"); html.AppendLine("Hello world!"); html.AppendLine("</body>"); html.AppendLine("</html>"); http.AppendLine("Content-Length:" + html.Length);//重要。 http.AppendLine(); http.AppendLine(html.ToString()); return Encoding.UTF8.GetBytes(http.ToString()); } } }
然后调用
using System; using System.Threading; namespace HttpTest { class Program { static void Main(string[] args) { int port = 8088; HttpServer server = new HttpServer(port); Thread thread = new Thread(server.Run); thread.IsBackground = true; thread.Start(); Console.WriteLine("服务启动成功,访问:http://127.0.0.1:" + port + "/"); Console.ReadKey(); server.Stop(); } } }
就这么简单。
实现过程遇到的几个问题,在这里记录。
1 Content-Lenght 是指 内容的长度。客户端(浏览器)根据这个值来判断数据是否接收完成。所以,这个应该是指转成byte的长度。在上面的程序中,直接使用字符串的长度。
2 头和html之间要空一行。
初次写网络程序(tcp), 欢迎大家拍砖,坐稳了。