webserver_webserver接口 - CSDN
精华内容
参与话题
  • WebServer的简单实现

    千次阅读 2017-09-19 18:16:33
    Web应用中,当HTTP服务器与多个客户端通信时,服务器会创建多个线程并行处理每个HTTP请求。HTTP通信又是建立在可靠的TCP连接之上,此时服务器一个端口(一般为80)就需要创建多个TCP连接,那么服务器是怎么处理? ...

    先来说一说问题。在Web应用中,当HTTP服务器与多个客户端通信时,服务器会创建多个线程并行处理每个HTTP请求。HTTP通信又是建立在可靠的TCP连接之上,此时服务器一个端口(一般为80)就需要创建多个TCP连接,那么服务器是怎么处理?

    首先我们必须清楚,一个TCP连接的唯一标识由:【源IP】+【源端口】+【目的IP】+【目的端口】四部分组成,这里需要特别注意。我当时错认为,对于服务器来说一个TCP连接只包括【源IP】+【源端口】,那么当多个客户端与服务器同一个端口创建连接时,那岂不是冲突了?后面认真的查阅了《TCP/IP详解》,才发现无论是服务器端还是客户端,一个本地唯一的TCP连接由【源IP】+【源端口】+【目的IP】+【目的端口】四部分组成。那么当某个端口已经被监听之后,我们就无法再创建一个新的TCP监听对象?这里以服务器80端口为例:

    当服务创建对80端口的TCP监听之后,意味着一个端口同时只能服务于同一个本地进程。也就说我们在代码中(这里使用C#代码):

    TcpListener myListener = new TcpListener(80);

    如果80端口已经被占用,那么系统就会报错,实例化TcpListener对象失败。

    当80端口处于监听状态时,就可以执行下一步TCP连接的建立了。TCP数据包到达服务器后,经过链路层、网络层处理之后,就送到TCP层,在Berkeley TCP/IP的实现代码中这个接口函数为:tcp_input()

    这个函数的预处理流程中有个环节叫做:Locate Internet PCB,定位因特网协议控制块。

    TCP maintains a one-behind cache (tcp_last_inpcb) containing the address of the PCB for the last received TCP segment. This is the same technique used by UDP. The comparison of the four element in the socket pair is in the same order as done by udp_input. If the cache entry does not match, in_pcblookup is called, and the cache is set to the new PCB entry.
    TCP does not have the same problem that we encountered with UDP: wildcard entries in the cache causing a high miss rate. The only time a TCP socket has a wildcard entry is for a server listening for connection requests. Once a connection is made, all four entries in the socket pair contain nonwildcard values.
    

    因为UDP是无状态,不需要建立连接,当有数据到来时,只需要根据【源IP】+【源端口】+【目的IP】+【目的端口】这四部分从缓存中查询PCB,如果不存在就调用in_pcblookup函数创建新的PCB入口。但是对于TCP来说,一旦连接建立之后,就不需要创建新的PCB。具体的处理是:如果PCB状态为CLOSED或者PCB不存在,那么就丢弃当前的数据。否则,就通过sonewconn函数创建一个新的socket连接。

    Lwip是参考Berkeley 对TCP/IP的实现,其具体处理流程如下:

    当TCP层接收到从IP层传来的tcp_datagram之后,统一由tcp_input()函数来处理,这里出现了三个分支:tcp_process()、tcp_timewait_input()、tcp_listen_input()。具体的处理流程如下图所示:


    从上边可以看出,TCP协议包中维护了整个TCP的连接状态,并通过回调机制实现与上层的通信,一般不建议在回调中做复杂的操作,因为回调的具体处理由内核完成,如果处理过程复杂或有异常,会导致内核的崩溃,为确保程序的安全可靠,一般在上层应用中采用查询的机制。下面以Web server为例,简单说明整个处理流程:

    WebServer.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    
    namespace web
    {
        class WebServer
        {
            // TCP监听对象
            private TcpListener myListener;
            // 监听端口
            private int port = 8080;
    
            // 实例化函数
            public WebServer()
            {
                try
                {
                    // 开始兼听端口
                    myListener = new TcpListener(port);
    
                    // 开始监听
                    myListener.Start();
                    Console.WriteLine("Web Server 运行中.. 按 ^C 停止运行...");
    
                    // 创建一个监听处理线程
                    Thread th = new Thread(new ThreadStart(StartListen));
                    th.Start();
                }
                catch (Exception e)
                {
                    Console.WriteLine("兼听端口时发生错误 :" + e.ToString());
                }
            }
    
            /*
             * SendHeader
             * @Description : 使用指定套接字发送头部数据
             * @param sHttpVersion: string, HTTP版本号字符串
             * @param sMIMEHeader : string, MIME头字符串
             * @param iTotBytes   : int, 数据长度
             * @param sStatusCode : string, 状态码
             * @param mySocket    : ref Socket, 套接字引用
             * @return      : none
             */
            public void SendHeader(string sHttpVersion, string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket mySocket)
            {
    
                String sBuffer = "";
                if (sMIMEHeader.Length == 0)
                {
                    sMIMEHeader = "text/html"; // 默认 text/html
                }
                sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n";
                sBuffer = sBuffer + "Server: cx1193719-b\r\n";
                sBuffer = sBuffer + "Content-Type: " + sMIMEHeader + "\r\n";
                sBuffer = sBuffer + "Accept-Ranges: bytes\r\n";
                sBuffer = sBuffer + "Content-Length: " + iTotBytes + "\r\n\r\n";
                Byte[] bSendData = Encoding.ASCII.GetBytes(sBuffer);
                SendToBrowser(bSendData, ref mySocket);
                Console.WriteLine("Total Bytes : " + iTotBytes.ToString());
            }
    
            public void SendToBrowser(String sData, ref Socket mySocket)
            {
                SendToBrowser(Encoding.ASCII.GetBytes(sData), ref mySocket);
            }
    
            /*
             * SendToBrowser
             * @Description : 通过套接字向浏览器发送信息
             * @param bSendData   : Byte[], 待发送信息数组
             * @param mySocket    : ref Socket, 套接字引用
             * @return            : none
             */
            public void SendToBrowser(Byte[] bSendData, ref Socket mySocket)
            {
                int numBytes = 0;
    
                try
                {
                    if (mySocket.Connected)
                    {
                        if ((numBytes = mySocket.Send(bSendData, bSendData.Length, 0)) == -1)
                            Console.WriteLine("Socket Error cannot Send Packet");
                        else
                        {
                            Console.WriteLine("No. of bytes send {0}", numBytes);
                        }
                    }
                    else
                        Console.WriteLine("连接失败....");
                }
                catch (Exception e)
                {
                    Console.WriteLine("发生错误 : {0} ", e);
    
                }
            }
            
            /*
             * StartListen
             * @Description : 监听线程,监听端口TCP连接,并进行处理
             * @return      : none
             */
            public void StartListen()
            {
                // 用于字符串中定位
                int iStartPos = 0;
                // 请求字符串
                String sRequest;
                // 请求资源的目录
                String sDirName;
                // 请求的文件
                String sRequestedFile;
                // 错误信息
                String sErrorMessage;
                // 本地目录
                String sLocalDir;
                // 注意设定你自己的虚拟目录
                String sMyWebServerRoot = "C:\\Cassini\\";
                // 格式化信息
                String sFormattedMessage = "";
                // 响应字符串
                String sResponse = "";
    
                // 不断遍历查询
                while (true)
                {
                    // 从监听的连接中获取一个新建立的连接,如果请求队列为空即还未有客户端发起TCP连接建立请求
                    // 该操作会被阻塞,直到新的连接到来。当接收到连接后,会返回一个Socket实例。
                    Socket mySocket = myListener.AcceptSocket();
    
                    Console.WriteLine("Socket Type " + mySocket.SocketType);
                    //如果为连接状态,说明有请求到来
                    if (mySocket.Connected)
                    {
                        Console.WriteLine("\nClient Connected!!\n==================\nCLient IP {0}\n", mySocket.RemoteEndPoint);
    
                        Byte[] bReceive = new Byte[1024];
    
                        //从套接字中取出数据到字节数组中
                        int i = mySocket.Receive(bReceive, bReceive.Length, 0);
    
                        //转换成字符串类型
                        string sBuffer = Encoding.ASCII.GetString(bReceive);
    
                        Console.WriteLine(sBuffer);
                        //只处理"get"请求类型
                        if (sBuffer.Substring(0, 3) != "GET")
                        {
                            Console.WriteLine("只处理get请求类型..");
                            mySocket.Close();
                            return;
                        }
    
                        // 查找 "HTTP" 的位置
                        iStartPos = sBuffer.IndexOf("HTTP", 1);
    
                        // 获取HTTP协议字符串
                        string sHttpVersion = sBuffer.Substring(iStartPos, 8);
    
                        // 得到请求类型和文件目录文件名
                        sRequest = sBuffer.Substring(0, iStartPos - 1);
    
                        // windows平台下目录分隔符
                        sRequest.Replace("\\", "/");
    
    
                        //如果结尾不是文件名也不是以"/"结尾则加"/"
                        if ((sRequest.IndexOf(".") < 1) && (!sRequest.EndsWith("/")))
                        {
                            sRequest = sRequest + "/";
                        }
    
    
                        // 获取请求的文件名
                        iStartPos = sRequest.LastIndexOf("/") + 1;
                        sRequestedFile = sRequest.Substring(iStartPos);
    
                        // 获取请求的文件目录
                        sDirName = sRequest.Substring(sRequest.IndexOf("/"), sRequest.LastIndexOf("/") - 3);
    
                        // 获取虚拟目录物理路径
                        sLocalDir = sMyWebServerRoot;
                        Console.WriteLine("请求文件目录 : " + sLocalDir);
    
                        // 目录不存在,返回404错误
                        if (sLocalDir.Length == 0)
                        {
                            sErrorMessage = "<H2>Error!! 请求的目录不存在</H2><Br>";
                            SendHeader(sHttpVersion, "", sErrorMessage.Length, " 404 Not Found", ref mySocket);
                            SendToBrowser(sErrorMessage, ref mySocket);
                            mySocket.Close();
                            continue;
                        }
    
    
                        if (sRequestedFile.Length == 0)
                        {
                            // 取得请求文件名
                            sRequestedFile = "index.html";
                        }
    
    
                        // 取得请求文件类型(设定为text/html)
                        String sMimeType = "text/html";
    
                        string sPhysicalFilePath = sLocalDir + sRequestedFile;
                        Console.WriteLine("请求文件: " + sPhysicalFilePath);
    
    
                        if (File.Exists(sPhysicalFilePath) == false)
                        {
    
                            sErrorMessage = "<script language='javascript'>alert('你好呀,我不是IIS服务器!');</script>";
                            //SendHeader(sHttpVersion, "", sErrorMessage.Length, " 404 Not Found", ref mySocket);
                            //SendToBrowser(sErrorMessage, ref mySocket);
                            byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(sErrorMessage);
                            SendHeader(sHttpVersion, sMimeType, bytes.Length, " 200 OK", ref mySocket);
                            SendToBrowser(bytes, ref mySocket);
                            //Console.WriteLine(sFormattedMessage);
                        }
                        else
                        {
                            int iTotBytes = 0;
                            sResponse = "";
    
                            // 打开文件资源句柄
                            FileStream fs = new FileStream(sPhysicalFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
    
                            // 打开文件二进制读取流
                            BinaryReader reader = new BinaryReader(fs);
                            // 暂存数组
                            byte[] bytes = new byte[fs.Length];
                            int read;
                            // 循环读取文件内容
                            while ((read = reader.Read(bytes, 0, bytes.Length)) != 0)
                            {
                                sResponse = sResponse + Encoding.ASCII.GetString(bytes, 0, read);
    
                                iTotBytes = iTotBytes + read;
    
                            }
                            // 关闭资源句柄
                            reader.Close();
                            fs.Close();
                            // 发送给浏览器
                            SendHeader(sHttpVersion, sMimeType, iTotBytes, " 200 OK", ref mySocket);
                            SendToBrowser(bytes, ref mySocket);
    
                        }
                        // 关闭socket
                        mySocket.Close();
                    }
                }
            }
        }
    }
    

    program.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace web
    {
        class Program
        {
            static void Main(string[] args)
            {
                WebServer web = new WebServer();
                Console.Read();
            }
        }
    }


    展开全文
  • webserver技术总结之一:webserver概念

    千次阅读 2019-06-14 18:03:22
    比如我们在开发项目的过程中,需要调用别的公司提供的数据,这里我们就需要使用到webserver。当前的应用程序开发逐步的呈现了两种迥然不同的倾向:1:基于浏览器的瘦客户端应用程序,2:基于浏览器的富客户端应用...

    一:为什么需要WebService

    大家或多或少都可能听说WebService,也可能用到过。比如我们在开发项目的过程中,需要调用别的公司提供的数据,这里我们就需要使用到webserver。当前的应用程序开发逐步的呈现了两种迥然不同的倾向:1:基于浏览器的瘦客户端应用程序,2:基于浏览器的富客户端应用程序(RIA)。当然后一种技术相对来说更加的时髦一些(如现在很流行的Html5技术),这里主要讲前者。

    基于浏览器的瘦客户端应用程序并不是 因为瘦客户能够提供更好的用户界面,而是因为它能够避免花在桌面应用程序发布上的高成本。发布桌面应用程序成本很高,

    一半是因为应用程序安装和配置的问 题,另一半是因为客户和服务器之间通信的问题。传统的Windows富客户应用程序使用DCOM来与服务器进行通信和调用远程对象。

    配置好DCOM使其在 一个大型的网络中正常工作将是一个极富挑战性的工作,同时也是许多IT工程师的噩梦。事实上,许多IT工程师宁愿忍受浏览器所带来的功能限制,

    也不愿在局 域网上去运行一个DCOM。关于客户端与服务器的通信问题,一个完美的解决方法是使用HTTP协议来通信。这是因为任何运行Web浏览器的机器都在使用 HTTP协议。

    同时,当前许多防火墙也配置为只允许HTTP连接。许多商用程序还面临另一个问题,那就是与其他程序的互操作性。如果所有的应用程序都是使用COM或.NET语言写的,

    并且都运行在Windows平台上,那就天下太平了。然而,事实上大多数商业数据仍然在大型主机上以非关系文件(VSAM) 的形式存放,并由COBOL语言编写的大型机程序访问。

    而且,目前还有很多商用程序继续在使用C++、Java、Visual Basic和其他各种各样 的语言编写。现在,除了最简单的程序之外,所有的应用程序都需要与运行在其他异构平台上

    的应用程序集成并进行数据交换。这样的任务通常都是由特殊的方法, 如文件传输和分析,消息队列,还有仅适用于某些情况的的API,

    如IBM的高级程序到程序交流(APPC)等来完成的。

    在以前,没有一个应用程序通信标 准,是独立于平台、组建模型和编程语言的。只有通过Web Service,客户端和服务器才能够自由的用HTTP进行通信,

    不论两个程序的平台和编程语言是什么。

    二:WebService的含义

    综上所述,WebService是一种跨编程语言和跨操作系统的远程调用技术。或者说是一种以HTTP协议为基础,通过xml进行客户端和服务器端通讯的框架或者组件。

    天气预报系统、淘宝网、校内网等会把自己的服务以web service的形式暴露出来,外界可以通过Web进行调用。我们调用这个web service的应用程序就是客户端,提供webservice服务的就是服务器端。

    值得注意的是,我们编写的webservice必须符合它的标准。

    三:WebService的实现原理

    XML+XSD,SOAP和WSDL就是构成WebService平台的三大技术。

    1:XML+XSD

    WebService采用HTTP协议传输数据,采用XML格式封装数据(即XML中说明调用远程服务对象的哪个方法,传递的参数是什么,

    以及服务对象的 返回结果是什么)。
    XML是WebService平台中表示数据的格式。除了易于建立和易于分析外,XML主要的优点在于它既是平台无关的,

    又是厂商无关 的。无关性是比技术优越性更重要的:软件厂商是不会选择一个由竞争对手所发明的技术的。 

    XML解决了数据表示的问题,但它没有定义一套标准的数据类型,更没有说怎么去扩展这套数据类型。

    例如,整形数到底代表什么?16位,32位,64位?

    这 些细节对实现互操作性很重要。XML Schema(XSD)就是专门解决这个问题的一套标准。它定义了一套标准的数据类型,

    并给出了一种语言来扩展这套数据类型。WebService平台就 是用XSD来作为其数据类型系统的。

    当你用某种语言(如VB.NET或C#)来构造一个Web service时,为了符合WebService标准,所 有你使用的数据类型都

    必须被转换为XSD类型。你用的工具可能已经自动帮你完成了这个转换,但你很可能会根据你的需要修改一下转换过程。

    2:SOAP

    WebService通过HTTP发送请求和接收结果。发送的请求内容和结果内容都采用xml格式封装,并增加了一些特定的HTTP消息头,

    这些特定的HTTP消息头和xml内容格式就是SOAP协议。

    SOAP协议=HTTP 协议+XML数据格式

    SOAP协议定义了SOAP消息的格式,SOAP协议是基于HTTP协议的,SOAP也是基于XML和XSD的,XML是SOAP的数据编码方式。

    打个比喻:HTTP就是普通公路,XML就是中间的绿色隔离带和两边的防护栏,SOAP就是普通公路经过加隔离带和防护栏改造过的高速公路。

    3:wsdl

    好比我们去商店买东西,首先要知道商店里有什么东西可买,然后再来购买,商家的做法就是张贴广告海报。 WebService也一样,

    WebService客户端要调用一个WebService服务,首先要有知道这个服务的地址在哪,以及这个服务里有什么方 法可以调用,

    所以,WebService务器端首先要通过一个WSDL文件来说明自己家里有啥服务可以对外调用,

    服务是什么(服务中有哪些方法,方法接受 的参数是什么,返回值是什么),服务的网络地址用哪个url地址表示,服务通过什么方式来调用。

    WSDL(Web Services Description Language)就是这样一个基于XML的语言,用于描述Web Service及其函数、参数和返回值。

    它是WebService客户端和服务器端都能理解的标准格式。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的,

    这将是一个很大的好处。一些最新的开发工具既能根据你的 Web service生成WSDL文档,又能导入WSDL文档,生成调用相应WebService的

    代理类代码。

    WSDL 文件保存在Web服务器上,通过一个url地址就可以访问到它。客户端要调用一个WebService服务之前,

    要知道该服务的WSDL文件的地址。

    WebService服务提供商可以通过两种方式来暴露它的WSDL文件地址:

    1.注册到UDDI服务器,以便被人查找;

    2.直接告诉给客户端调用者。

    四:WebService开发

    Webservice开发分为:服务端开发和客户端开发。

    1:服务端开发

    把公司内部系统的业务方法发布成WebService服务,供远程合作单位和个人调用。

    (借助一些WebService框架可以很轻松地把自己的业务对象发布成WebService服务,

    Java方面的典型WebService框架包括:axis,xfire,cxf 等,java ee服务器通常也支持发布WebService服务,例如JBoss。)

    2:客户端开发

    调用别人发布的WebService服务,大多数人从事的开发都属于这个方面,例如,调用天气预报WebService服务。

    (使用厂 商的WSDL2Java之类的工具生成静态调用的代理类代码;

    使用厂商提供的客户端编程API类;使用SUN公司早期标准的jax-rpc开发包;使用 SUN公司最新标准的jax-ws开发包。当然SUN已被ORACLE收购)

    3:WebService原理

    1:编写好WebService服务端后,需要向UUID服务器注册供别人使用。

    2:客户端去UUID服务器上查询自己需要的WebService。

    3:客户端向WebService提供者询问确切的调用方法

    4:WebService服务器向客户端发送一个Wsdl文件。该WSDL文件描述了它所能提供的所有方法接口。

    5:客户端了解之后,将WSDL中描述的接口方法封装成HTTP请求,发送给WebService服务器。

    6:WebService服务器端响应客户端发送的HTTP请求,将处理结果以同样的SOAP报文形式通过HTTP协议发送给客户端。

    参考资料:

    http://www.cnblogs.com/xdp-gacl/p/4048937.html

    http://blog.csdn.net/ostrichmyself/article/details/6393627

    展开全文
  • 什么是WEBserver? 经常使用的WEBserver有哪些?   一、什么是WEBserver  Webserver能够解析HTTP协议。当Webserver接收到一个HTTP请求,会返回一个HTTP响应,比如送回一个HTML页面。为了处理一个请求Webserver能够...

    什么是WEBserver? 经常使用的WEBserver有哪些?

     
    一、什么是WEBserver

        Webserver能够解析HTTP协议。当Webserver接收到一个HTTP请求,会返回一个HTTP响应,比如送回一个HTML页面。为了处理一个请求Webserver能够响应一个静态页面或图片,进行页面跳转或者把动态响应的产生托付给一些其他的程序比如CGI脚本,JSP脚本,servlets,ASP脚本,server端JavaScript,或者一些其他的server端技术。不管它们(译者注:脚本)的目的怎样,这些server端的程序通常产生一个HTML的响应来让浏览器能够浏览。 

     

    二。经常使用的WEBserver有哪些?

         在UNIX和LINUX平台下使用最广泛的免费HTTPserver是W3C、NCSA和APACHEserver,而Windows平台NT/2000/2003使用IIS的WEBserver。在选择使用WEBserver应考虑的本身特性因素有:性能、安全性、日志和统计、虚拟主机、代理server、缓冲服务和集成应用程序等,以下介绍几种经常使用的WEBserver。

     

    Microsoft IIS
         Microsoft的Webserver产品为Internet Information Server (IIS), IIS 是同意在公共Intranet或Internet上公布信息的Webserver。IIS是眼下最流行的Webserver产品之中的一个,非常多著名的站点都是建立在IIS的平台上。IIS提供了一个图形界面的管理工具,称为 Internet服务管理器,可用于监视配置和控制Internet服务。

         IIS是一种Web服务组件,当中包含Webserver、FTPserver、NNTPserver和SMTPserver,分别用于网页浏览、文件传输、新闻服务和邮件发送等方面,它使得在网络(包含互联网和局域网)上公布信息成了一件非常easy的事。它提供ISAPI(Intranet Server API)作为扩展Webserver功能的编程接口;同一时候,它还提供一个Internet数据库连接器,能够实现对数据库的查询和更新。

     

    IBM WebSphere
         WebSphere Application Server 是 一 种功能完好、开放的Web应用程序server,是IBM电子商务计划的核心部分,它是基于 Java 的应用环境,用于建立、部署和管理 Internet 和 Intranet Web 应用程序。 这一整套产品进行了扩展,以适应 Web 应用程序server的须要,范围从简单到高级直到企业级。

         WebSphere 针对以 Web 为中心的开发者,他们都是在基本 HTTPserver和 CGI 编程技术上成长起来的。IBM 将提供 WebSphere 产品系列,通过提供综合资源、可反复使用的组件、功能强大并易于使用的工具、以及支持 HTTP 和 IIOP 通信的可伸缩执行时环境,来帮助这些用户从简单的 Web 应用程序转移到电子商务世界。

     

    BEA WebLogic
         BEA WebLogic Server 是一种多功能、基于标准的web应用server,为企业构建自己的应用提供了坚实的基础。各种应用开发、部署全部关键性的任务,不管是集成各种系统和数据库,还是提交服务、跨 Internet 协作,起始点都是 BEA WebLogic Server。因为 它具有全面的功能、对开放标准的遵从性、多层架构、支持基于组件的开发,基于 Internet 的企业都选择它来开发、部署最佳的应用。

         BEA WebLogic Server 在使应用server成为企业应用架构的基础方面继续处于率先地位。BEA WebLogic Server 为构建集成化的企业级应用提供了稳固的基础,它们以 Internet 的容量和速度,在连网的企业之间共享信息、提交服务,实现协作自己主动化。

     

    APACHE

         apache仍然是世界上用的最多的Webserver,市场占有率达60%左右。它源于NCSAhttpdserver,当NCSA WWWserver项目停止后,那些使用NCSA WWWserver的人们開始交换用于此server的补丁,这也是apache名称的由来(pache 补丁)。世界上非常多著名的站点都是Apache的产物,它的成功之处主要在于它的源码开放、有一支开放的开发队伍、支持跨平台的应用(能够执行在差点儿全部的Unix、Windows、Linux系统平台上)以及它的可移植性等方面。

     

    Tomcat
         Tomcat是一个开放源码、执行servlet和JSP Web应用软件的基于Java的Web应用软件容器。Tomcat Server是依据servlet和JSP规范进行执行的,因此我们就能够说Tomcat Server也实行了Apache-Jakarta规范且比绝大多数商业应用软件server要好。
         Tomcat是Java Servlet 2.2和JavaServer Pages 1.1技术的标准实现,是基于Apache许可证下开发的自由软件。Tomcat是全然重写的Servlet API 2.2和JSP 1.1兼容的Servlet/JSP容器。Tomcat使用了JServ的一些代码,特别是Apache服务适配器。随着Catalina Servlet引擎的出现,Tomcat第四版号的性能得到提升,使得它成为一个值得考虑的Servlet/JSP容器,因此眼下很多WEBserver都是採用Tomcat。
    眼下,很多大型Web应用一般将Apache和Tomcat结合使用,Apache负责接收用户的HTTP请求,假设请求是Servlet、Jsp,则把请求转发给Tomcat处理,并将处理结果封装响应给用户。

    展开全文
  • 使用Java实现一个最简单的Web Server

    万次阅读 2017-08-28 23:42:30
    Hello Web ServerWeb Server没有你想象的那么难实现(当然要实现一个好的Java Web Server还是很有难度...我们先来一个屌丝版,这个屌丝版能显示Hello Web Serverpackage exec.network.webserver;import java.io.Buffer

    Hello Web Server

    Web Server没有你想象的那么难实现(当然要实现一个好的Java Web Server还是很有难度的)。你只要明白基本的HTTP协议,TCP编程和IO知识。当然,你也要会最简单的HTML代码。

    我们先来一个屌丝版,这个屌丝版能显示Hello Web Server

    package exec.network.webserver;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class SimpleHttpServer {
        private final static int TCP_PORT = 9090;
    
        public static void main(String[] args) throws IOException {
            ServerSocket ss = new ServerSocket(TCP_PORT);
            Socket socket = ss.accept();
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
            String buffer = null;
            while ((buffer = br.readLine()) != null && !s.equals("")) {
                System.out.println(buffer);
            }
    
            BufferedWriter bw = new BufferedWriter(
                    new OutputStreamWriter(socket.getOutputStream()));
            bw.write("HTTP/1.1 200 OK\n");
            bw.write("Content-Type: text/html; charset=UTF-8\n\n");
            bw.write("<html>\n" + "<head>\n" + "    <title>first page</title>\n"
                    + "</head>\n" + "<body>\n" + "    <h1>Hello Web Server!</h1>\n"
                    + "</body>\n" + "</html>\n");
            bw.flush();
            bw.close();
    
            br.close();
            socket.close();
            ss.close();
        }
    }

    运行这个程序,然后再浏览器里敲:http://localhost:9090/,页面上会出现一个大大的Hello Web Server。然后,就没有然后了……

    静态网页版

    看了上面的程序,你可能都会说,太屌丝了,不行,继续。

    我们来加强这个Web Server。

    准备示例的静态页面文件

    准备一个webroot文件夹,里面放个index.htm文件,再准备一个01.jpg文件,作为图片放进去。这个是我们准备的index.htm,图片就不展示了。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
    <h2>HTTP SERVER</h2>
    <p>Where there is a will, there is a way.</p>
    <img src="01.jpg"  />
    </body>
    </html>
    

    准备HttpServer和Request,Response程序

    1. HttpServer
    package exec.network.webserver;
    
    import java.io.File;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class HttpServer {
        private static final int SERVER_PORT = 9090;
        public static final String WEB_ROOT = System.getProperty("user.dir")
                + File.separator + "webroot";
        private static final String SHUTDOWN_COMMAND = "/QUIT";
    
        public static void main(String[] args) {
            HttpServer server = new HttpServer();
            server.await();
        }
    
        public void await() {
            ServerSocket serverSocket = null;
            try {
                serverSocket = new ServerSocket(SERVER_PORT);
            }
            catch (Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
    
            while(true) {
                Socket socket = null;
                InputStream input = null;
                OutputStream output = null;
                try {
                    socket = serverSocket.accept();
                    input = socket.getInputStream();
                    output = socket.getOutputStream();
    
                    // 创建Request对象并解析
                    Request request = new Request(input);
                    request.parse();
                    // 检查是否是关闭服务命令
                    if (request.getUri().equals(SHUTDOWN_COMMAND)) {
                        break;
                    }
    
                    // 创建 Response 对象
                    Response response = new Response(output);
                    response.setRequest(request);
                    response.sendStaticResource();
    
                    // 关闭 socket 对象
                    socket.close();
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    1. Request
    package exec.network.webserver;
    
    import java.io.InputStream;
    
    public class Request {
        private final static int BUFFER_SIZE = 1024;
        private InputStream input;
        private String uri;
    
        public Request(InputStream input) {
            this.input = input;
        }
    
        public void parse() {
            StringBuffer request = new StringBuffer();
            int readLength;
            byte[] buffer = new byte[BUFFER_SIZE];
    
            try {
                readLength = input.read(buffer);
            } catch (Exception e) {
                e.printStackTrace();
                readLength = -1;
            }
            for(int i = 0; i < readLength; i++) {
                request.append((char)buffer[i]);
            }
            System.out.print(request.toString());
            uri = parseUri(request.toString());
        }
    
        private String parseUri(String requestString) {
            int index1, index2;
            index1 = requestString.indexOf(' ');
            if (index1 != -1) {
                index2 = requestString.indexOf(' ', index1 + 1);
                if (index2 > index1)
                    return requestString.substring(index1 + 1, index2);
            }
            return null;
        }
    
        public String getUri() {
            return uri;
        }
    }
    
    1. Response
    package exec.network.webserver;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    
    public class Response {
        private static final int BUFFER_SIZE = 1024;
        Request request;
        OutputStream output;
    
        public Response(OutputStream output) {
            this.output = output;
        }
    
        public void setRequest(Request request) {
            this.request = request;
        }
    
        public void sendStaticResource() throws IOException{
            byte[] buffer = new byte[BUFFER_SIZE];
            FileInputStream fis = null;
            try {            
                File file = new File(
                        HttpServer.WEB_ROOT, request.getUri());
                if(file.exists()) {
                    output.write("HTTP/1.1 200 OK\n".getBytes());
                    output.write("Content-Type: text/html; charset=UTF-8\n\n".getBytes());
                    fis = new FileInputStream(file);
                    int readLength;
                    while((readLength = fis.read(buffer, 0, BUFFER_SIZE)) > 0 ) {
                        output.write(buffer, 0, readLength);
                    }
                }
                else {
                    String errMsg = "HTTP/1.1 404 File Not Found\r\n" + "Content-Type: text/html\r\n"
                            + "Content-Length: 23\r\n" + "\r\n" + "<h1>File Not Found</h1>";
                    output.write(errMsg.getBytes());
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            finally {
                if(fis != null) {
                    fis.close();
                }
            }
        }
    }
    

    好了,最简单的Web Server我们已经用Java实现了,简单吧。

    参考资料

    http://www.cnblogs.com/chenpi/p/5602171.html

    展开全文
  • webserver总结

    千次阅读 2018-08-05 16:45:32
    前言 tomcat之外的其他webserver 小结
  • web 服务器有哪些

    万次阅读 2018-08-27 16:53:49
    什么是web服务器 "网络服务"(Web Service)的本质,就是通过网络调用其他网站的资源。 Web Service架构和云 如果一个软件的主要部分采用了"网络服务",即它把存储或计算环节"外包"...
  • webServer安装及配置详情

    千次阅读 2018-09-03 15:02:06
    apache 基本操作 安装 yum install httpd 启动 service httpd start 停止 service httpd stop 安装apache后 ,cd /etc/httpd/conf vim http ...
  • web server(web服务器)简单了解

    千次阅读 2017-10-24 17:29:50
    web server简单了解(一)
  • Webserver 基于ws超级简单入门

    千次阅读 2018-11-18 12:17:31
    基于mavn  项目目录结构 pom.xml &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;project xmlns="http://maven.apache.org/POM/4.0.0"... ...
  • 轻量级的web server

    千次阅读 2013-02-20 08:45:53
    web接口是一个应用系统常用的接口,本文所说的轻量级的web server是指应用系统不以web访问为主,web接口提供辅助作用,例如,修改配置等,此时,对web server的要求是程序简单、无或者很轻的并发、能嵌入到应用中...
  • Web Server

    千次阅读 2017-12-10 20:35:17
    初步理解  Web server就是一台由各种编程语言建立起来提供网页的电脑,最常见的是通过Http协议传给客户端的网页浏览器。   另一方面也可以说这是一个提供网页的服务器程序。常见产品  · Apache软件基金会的...
  •     在前面章节的博客中,博主介绍了ESP8266WiFi库 Tcp server的用法,并模拟了Http webserver的功能。但是,可以看出通过Tcp server 处理http请求,我们需要自己解析请求协议以及判断各种数据,稍微不小心就很...
  • 目的 开启服务器 监听客户端 Web的请求与响应 实现Web Server功能 用过网页收发数据 建立网页 完善Web Server功能 总结
  • web serverweb service区别(摘抄)

    千次阅读 2012-08-31 10:37:06
    web serverweb服务器,web service应用服务器。在应用服务器出现之前,就已经出现了web服务器。 简单的说能实现动态网页技术的服务器叫做应用服务器。 Web服务器主要是表现层Jsp MVC之类,而应用服务器是运行...
  • 本文主要讲述如何用C/C++写一个...项目地址:https://github.com/imndszy/webserver在编写一个服务器之前,我们需要对socket以及网络协议尤其是http协议有基础的了解,如果不了解,请参阅Beej’s Guide to Network Prog
  • 几种轻量级web server的比较

    千次阅读 2008-10-13 15:15:00
    1. TUX2.... 几种web server表现的对比4. 我的总结 TUX http://www.chinadesign.com.cn/NewsContents1.asp?id=3386 tux是一种有GPL(GNU General Public License )许可的基于内核的Web服务器。
  • webServer 接口开发

    万次阅读 2014-05-06 15:21:26
    开发一个webserver需要服务器短和客户端:一般而言客户端负责请求,服务端负责响应,那么怎么开发一个服务端呢,我们知道客户端是通过服务器的描述文件生成或者手动编写,这里我推荐用myeclipse生成比较简单,只要...
  • 使用Arduino开发ESP32(09):WebServer使用演示与说明

    千次阅读 热门讨论 2019-04-25 12:42:04
    文章目录目的总结 目的 总结
  • Web server, WSGI和Web framework

    千次阅读 2017-04-25 22:34:01
    WSGI把Web服务器和Web框架结合起来:WSGI server所做的工作仅仅是将从客户端收到的请求传递给WSGI application,然后将WSGI application的返回值作为响应传给客户端。有了这一层抽象,服务器可以在不修改代码的情况...
  • 用Python实现简单的Web Server

    千次阅读 2019-05-02 17:05:43
    Web Server的概念 用Python实现Web Server Python 2中SimpleHTTPServer模块被合并到Python 3的http.server模块。它支持目录浏览,指定端口,指定绑定地址等。 方法一:直接在命令行调用http.server模...
1 2 3 4 5 ... 20
收藏数 1,262,853
精华内容 505,141
关键字:

webserver