共同成长
故不积跬步,无以至千里;不积小流,无以成江海。

导航

 

最近实现一套简单的网络程序。为了查看程序内部的变量,方便调试。就在想搞一个最最简单的方式。第一个想到写文件,日志。这个不实时,而且打开麻烦,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), 欢迎大家拍砖,坐稳了。

 

posted on 2017-01-12 15:00  码有钱  阅读(986)  评论(0编辑  收藏  举报