• 基于TcpListener实现最简单的http服务器


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

  • 相关阅读:
    SpringBoot java.lang.IllegalArgumentException: Request header is too large
    (转)以太坊 钱包 创建 导入 Keystore
    (转)以太坊数据同步常见问题集锦
    以太坊nonce
    (转)Fabric 1.0 读写集
    (转)Fabric CA环境的集成
    Hyperledger Fabric CA的命令行用法
    oracle新建表空间与用户
    积分智能合约
    远程桌面,身份验证错误:要求的函数不正确等解决办法
  • 原文地址:https://www.cnblogs.com/goodfulcom/p/6278292.html
Copyright © 2020-2023  润新知