精华内容
下载资源
问答
  • 相信很多人在socket编程学习过程中,都会遇到类似的web服务器的设计案例,可是对于刚接触socket的新手来说,往往难以迈出第一步,于是在此分享一个多线程的web服务器代码(参考计算机网络课程的代码框架),便于各位...

    相信很多人在socket编程学习过程中,都会遇到类似的web服务器的设计案例,可是对于刚接触socket的新手来说,往往难以迈出第一步,于是在此分享一个多线程的web服务器代码(参考计算机网络课程的代码框架),便于各位网友参考学习使用!

     

    一、理解多线程

    多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。

    线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。

    多个线程的执行是并发的,也就是在逻辑上同时,而不管是否是物理上的同时。如果系统只有一个单核CPU,那么真正的同时是不可能的。不过,由于CPU的处理速度非常快,用户感觉好像自己的程序连续运行一样。

    多线程和传统的单线程在程序设计上最大的区别在于,由于各个线程的控制流彼此独立,使得各个线程之间的代码是乱序执行的

    二、案例需求

    以JDK为开发工具,利用Socket通信机制实现一个多线程的WEB服务器,该服务器具有以下功能:

    1. 能够并行服务于多个请求。
    2. 对于每个请求,显示接收到的HTTP请求报文的内容,并产生适当的响应(若找到用户请求对象,则返回该对象。否则发送一个包含适当提示信息的响应消息,从而可以在浏览器窗口中显示差错信息。

    三、代码部分

    
    
    import java.io.*;
    import java.net.*;
    import java.util.*;
    
    public final class WebServer {
    	public static void main(String argv[]) throws Exception {
    		int port = 6666;//定义端口号
    		ServerSocket welcomeSocket = new ServerSocket(port);
    		while (true) {
    			Socket connectionSocket = welcomeSocket.accept();
    			HttpRequest request = new HttpRequest(connectionSocket);
    			Thread thread = new Thread(request);
    			thread.start();
    		}
    	}
    }
    
    final class HttpRequest implements Runnable {
    	final static String CRLF = "\r\n";
    	Socket socket;
    
    	public HttpRequest(Socket socket) throws Exception {
    		this.socket = socket;
    	}
    
    	public void run() {
    		try {
    			processRequest();
    
    		} catch (Exception e) {
    			System.out.println(e);
    		}
    	}
    
    	private void processRequest() throws Exception {
    		InputStream is = socket.getInputStream();
    		DataOutputStream os = new DataOutputStream(socket.getOutputStream());
    
    		BufferedReader br = new BufferedReader(new InputStreamReader(is));
    		String requestLine = br.readLine();
    		System.out.println();
    		System.out.println(requestLine);
    		String headerLine = null;
    		while ((headerLine = br.readLine()).length() != 0) {
    			System.out.println(headerLine);
    		}
    		
    		// 从请求行中提取出文件名
    		StringTokenizer tokens = new StringTokenizer(requestLine);
    		tokens.nextToken(); // 跳过method
    		String fileName = tokens.nextToken();
    		fileName = "." + fileName;//构造请求文件名
    		
    
    		FileInputStream fis = null;
    		boolean fileExists = true;
    		// 判断请求对象是否存在
    		try {
    			fis = new FileInputStream(fileName);
    		} catch (FileNotFoundException e) {
    			fileExists = false;
    		}
    		String statusLine = null;
    		String contentTypeLine = null;
    		String entityBody = null;
    
    		if (fileExists) {// 请求文件存在构造响应的status 和 contentType
    			statusLine = "HTTP/1.1 200 OK" + CRLF;
    			contentTypeLine = "Content-type: " + contentType(fileName) + CRLF;
    		} else {// 请求文件不存在
    			statusLine = "HTTP/1.1 404" + CRLF;
    			contentTypeLine = "Content-type: " + contentType(fileName) + CRLF;
    			entityBody = "<!DOCTYPE html><HTML>" + "<HEAD><TITLE>Not Found</TITLE></HEAD>" + "<BODY>Not Found</BODY></HTML>";
    		}
    		os.writeBytes(statusLine);
    		os.writeBytes(contentTypeLine);
    		os.writeBytes(CRLF);
    		if (fileExists) {
    			sendBytes(fis, os);
    			fis.close();
    		} else {
    			os.writeBytes(entityBody);
    		}
    		os.close();
    		br.close();
    		socket.close();
    	}
    
    	private static void sendBytes(FileInputStream fis, OutputStream os) throws Exception {
    		byte[] buffer = new byte[1024];
    		int bytes = 0;
    		while ((bytes = fis.read(buffer)) != -1) {
    			os.write(buffer, 0, bytes);
    		}
    
    	}
    
    	private static String contentType(String fileName)
    
    	{
                    //根据文件名返回相应的contentType
    		if (fileName.endsWith(".htm") || fileName.endsWith(".html")) {
    			return "text/html";
    		}
    		if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
    			return "image/jpeg";
    		}
    		if (fileName.endsWith(".png")) {
    			return "image/png";
    		}
    		if (fileName.endsWith(".css")) {
    			return "text/css";
    		}
    		if (fileName.endsWith(".gif")) {
    			return "image/gif";
    		}
    		if (fileName.endsWith(".png")) {
    			return "image/png";
    		}
    		return "application/octet-stream";
    	}
    
    }

    四、代码测试

    测试时使用浏览器访问localhost:port,本例为127.0.0.1:6666,测试用的文件放在项目根目录即可,如使用eclipse编写的项目则需要将文件放在项目名称的目录下(有bin和src的那个目录)

    测试截图如下

    请求成功时正确返回请求文件

    请求失败时给出提示

    展开全文
  • 什么是MVC编程模式 ? MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件...

    23种设计模式+额外常用设计模式汇总 (持续更新)

    什么是MVC编程模式 ?

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中

    MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。
    后来多用于Web程序设计中,前端View提供数据模型展示和人机交互,Controller 接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。 起到了一个调度服务的作用。Mode模型层原来是包括数据和服务层,现在一般分开处理数据和服务层。

    模型-视图-控制器模式是一个有用的工具箱,它有很多好处,但也有一些缺点。

    MVC模式都出现了好久了,为啥还要学?

    我问了几个工作了的程序员(不是什么大牛,说的不对可以指正)大厂和特殊的厂可能会玩一些的花的,但是很多公司仍是绕不开MVC和三层架构(不一样都是三个,千万不可混淆)。MVC仍是经典的Web开发的编程模式。
    为什么GOF四人帮设计模式没有写这个设计模式?
    我个人觉得主要是当时要解决的问题和后来的解决的问题不一样,随着时代发展,而生产出的这个设计模式。深挖一下不难发现MVC模式是组合模式、策咯模式、观察者模式的一个结合体。其中View层,单独实现了组合模式Model层和View层,实现了观察者模式View层和Controller层,实现了策咯模式

    MVC应用

    一个非常好的应用就是 Struts框架。 Struts是最早的Java开源框架之一,它是MVC设计模式的一个优秀实现。 Struts定义了通用的Controller(控制器),通过配置文件(通常是 Struts -config.xml)
    Struts是最早的java开源框架之一,它是MVC设计模式的一个优秀实现。 Struts定义了通用的Controller(控制器),通过配置文件(通常是 Struts -config.xml)隔离Model(模型)和View(视图),以Action的概念以对用户请求进行了封装,使代码更加清晰易读。 Struts还提供了自动将请求的数据填充到对象中以及页面标签等简化编码的工具。 Struts能够开发大型Java Web项目。

    在这里插入图片描述
    在这里插入图片描述
    图是在网上找的,不要骂我!

    优点

    1.耦合性低

    视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码,同样,一个应用的业务流程或者业务规则的改变只需要改动MVC的模型层即可。因为模型与控制器和视图相分离,所以很容易改变应用程序的数据层和业务规则。

    2.重用性高

    MVC模式允许使用各种不同样式的视图来访问同一个服务器端的代码,因为多个视图能共享一个模型,它包括任何WEB(HTTP)浏览器或者无线浏览器(wap),比如,用户可以通过电脑也可通过手机来订购某样产品,虽然订购的方式不一样,但处理订购产品的方式是一样的。由于模型返回的数据没有进行格式化,所以同样的构件能被不同的界面使用。

    3.部署快,生命周期成本低

    MVC使开发和维护用户接口的技术含量降低。使用MVC模式使开发时间得到相当大的缩减,它使程序员(Java开发人员)集中精力于业务逻辑,界面程序员(HTML和JSP开发人员)集中精力于表现形式上。

    4.可维护性高

    分离视图层和业务逻辑层也使得WEB应用更易于维护和修改。

    缺点

    1.没有很明确的定义,完全理解MVC比较复杂。
    现在学习处于断层,前边的人学完了扔了,后边的人不愿意用,到现在没啥可说的,时代就这样。

    2.调试困难。

    因为模型和视图要严格的分离,这样也给调试应用程序带来了一定的困难,每个构件在使用之前都需要经过彻底的测试。

    3.不适合小型,中等规模的应用程序

    在一个中小型的应用程序中,强制性的使用MVC进行开发,花费大量时间将MVC应用到规模并不是很大的应用程序通常会得不偿失,完全显示不出MVC的优点。

    4.增加系统结构和实现的复杂性

    对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。

    5.视图与控制器间的过于紧密的连接并且降低了视图对模型数据的访问

    视图与控制器是相互分离,但却是联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。

    6.效率问题
    依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。

    7.毕竟是整合了三种设计模式,还是有一部分的缺点没有得到消除。

    最经典的MVC实现

    最典型的MVC就是jsp+servlet+javabean模式,也就是很多高校里讲的那种,有幸我就是一员。

    JavaBean作为模型,既可以作为数据模型来封装业务数据,又可以作为业务逻辑模型来包含应用的业务操作。其中,数据模型用来存储或传递业务数据,而业务逻辑模型接收到控制器传过来的模型更新请求后,执行特定的业务逻辑处理,然后返回相应的执行结果。

    JSP作为表现层,负责提供页面为用户展示数据,提供相应的表单(Form)来用于用户的请求,并在适当的时候(点击按钮)向控制器发出请求来请求模型进行更新,JSP虽然可以使用Html的功能,但是毕竟是动态的,效率还是有一定问题的。

    Serlvet作为控制器,用来接收用户提交的请求,然后获取请求中的数据,将之转换为业务模型需要的数据模型,然后调用业务模型相应的业务方法进行更新,同时根据业务执行结果来选择要返回的视图。
    在这里插入图片描述

    这篇文章借鉴了不少,看了挺多的东西,才大致弄明白是什么意思,他不像其他的设计模式,这个只有一个定义,大概就是这个样子的,你按这个来。哈哈哈,一开始看的我挺蒙的,这是啥玩意,再看第二遍的时候,我就能明白了。如果不明白,多看几遍。

    展开全文
  • HTTP学习与Web服务器编程

    千次阅读 2017-11-20 00:00:28
    这次的主题是查找HTTP协议的相关资料,基于此编写一个简单的Web服务器。 需要完成的几大主要的要求有: 1)编写一个简单的Web服务器;...6)扩展编写的简单Web服务器,使浏览器能够浏览Web上存储

    这次的主题是查找HTTP协议的相关资料,基于此编写一个简单的Web服务器。
    需要完成的几大主要的要求有:
    1)编写一个简单的Web服务器;
    2)实现的服务器应能与标准的浏览器进行简单的交互;
    3)记录浏览器与服务的交互过程;
    4)利用HTML语言编写网页浏览器可通过编写的Web服务器正常访问该网页;
    5)支持多用户并发访问;
    6)扩展编写的简单Web服务器,使浏览器能够浏览Web上存储的图像

    一.了解http协议(参考百度百科)

    HTTP是一个客户端和服务器端请求和应答的标准(TCP)。客户端是终端用户,服务器端是网站。通过使用Web浏览器、网络爬虫或者其它的工具,客户端发起一个到服务器上指定端口(默认端口为80)的HTTP请求。(我们称这个客户端)叫用户代理,应答的服务器上存储着(一些)资源,比如HTML文件和图像;(我们称)这个应答服务器为源服务器。“客户”与“服务器”是一个相对的概念,只存在于一个特定的连接期间,即在某个连接中的客户在另一个连接中可能作为服务器。基于HTTP协议的客户/服务器模式的信息交换过程,它分四个过程:建立连接、发送请求信息、发送响应信息、关闭连接。
    HTTP协议是基于请求/响应范式的。一个客户机与服务器建立连接后,发送一个请求给服务器,请求方式的格式为,统一资源标识符、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。服务器接到请求后,给予相应的响应信息,其格式为一个状态行包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
    其实简单说就是任何服务器除了包括HTML文件以外,还有一个HTTP驻留程序,用于响应用户请求。你的浏览器是HTTP客户,向服务器发送请求,当浏览器中输入了一个开始文件或点击了一个超级链接时,浏览器就向服务器发送了HTTP请求,此请求被送往由IP地址指定的URL。驻留程序接收到请求,在进行必要的操作后回送所要求的文件。在这一过程中,在网络上发送和接收的数据已经被分成一个或多个数据包,每个数据包包括:要传送的数据;控制信息,即告诉网络怎样处理数据包。TCP/IP决定了每个数据包的格式。如果事先不告诉你,你可能不会知道信息被分成用于传输和再重新组合起来的许多小块。
    HTTP报文由从客户机到服务器的请求和从服务器到客户机的响应构成。
    请求报文格式为:请求行 - 通用信息头 - 请求头 - 实体头 - 报文主体。请求行以方法字段开始,后面分别是 URL 字段和 HTTP 协议版本字段,并以 CRLF 结尾。SP 是分隔符。除了在最后的 CRLF 序列中 CF 和 LF 是必需的之外,其他都可以不要。有关通用信息头,请求头和实体头方面的具体内容可以参照相关文件。
    应答报文格式为:状态行 - 通用信息头 - 响应头 - 实体头 - 报文主体。状态码元由3位数字组成,表示请求是否被理解或被满足。原因分析是对原文的状态码作简短的描述,状态码用来支持自动操作,而原因分析用来供用户使用。客户机无需用来检查或显示语法。有关通用信息头,响应头和实体头方面的具体内容可以参照相关文件。
    简而言之,使用http就像我们打电话订货一样,我们可以打电话给商家,告诉他我们需要什么规格的商品,然后商家再告诉我们什么商品有货,什么商品缺货。这些,我们是通过电话线用电话联系(HTTP是通过TCP/IP),当然我们也可以通过传真,只要商家那边也有传真。

    二.建立简单的web服务器
    我们将使用java语言,基于java.net.Socket和java.net.ServerSocket实现一个简单的web服务器。

    首先我们来看一下整个程序的大致结构(使用的IDE为eclipse):
    这里写图片描述
    有三个Java类,分别是服务器类MyWebServer.java和需要在服务器类里调用的Request类和Responses类,分别用来处理接收到的http协议报文的解析工作和响应工作。在本工程目录下建一个文件夹resource用来储存所有的html文件和图片。

    现在主要说说整个程序的思路:
    1.创建一个ServerSocket对象;
    2.调用ServerSocket对象的accept方法,等待连接,连接成功会返回一个Socket对象,否则一直阻塞等待;
    3.从Socket对象中获取InputStream和OutputStream字节流,这两个流分别对应request请求和response响应;
    4.处理请求:读取InputStream字节流信息,转成字符串形式,并解析
    5.处理响应:根据解析出来的uri信息,从WEB_ROOT目录中寻找请求的资源资源文件, 读取资源文件,并将其写入到OutputStream字节流中;
    6.关闭Socket对象;
    7.转到步骤2,继续等待连接请求;

    (1)服务器类

    //MyWebServer.java
    package homework3;
    
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.PrintStream;
    import java.net.InetAddress;  
    import java.net.ServerSocket;  
    import java.net.Socket;
    
    
    
    public class MyWebServer {
            public static int PORT=8888;
            public static final String WEB_ROOT="resource";  
            public static void main(String[] args) { 
                System.out.println("开启服务器");
                try {
                    ServerSocket WebServer=null;
                    WebServer = new ServerSocket(PORT,1,InetAddress.getByName("127.0.0.1"));
                    while(true)
                    //不断循环监听是否有新的请求,有的话启动一个线程响应
                    {
                        Socket Client=WebServer.accept();
                        new HttpConnectThread(Client).start();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }  
            }  
    }
    
    
    
    class HttpConnectThread extends Thread
    {
        private Socket Client;
        public HttpConnectThread(Socket s)
        {
            Client=s;
        }
    
    
        public void run()
        {
            try {
                InputStream input=null;
                OutputStream output=null;
                input=Client.getInputStream();
                output=Client.getOutputStream();
                //从Socket对象中获取InputStream和OutputStream字节流,
                //这两个流分别对应request请求和response响应;
                Request request=new Request(input);
                if(request.parse(Client)==1){
            //处理请求:读取InputStream字节流信息,转成字符串形式,并解析
                    Response response=new Response(output);  
                    response.setRequest(request);  
                    response.sendStaticResource(Client);
                }
            //处理响应:根据解析出来的信息,从WEB_ROOT目录中寻找请求的资源资源文件,
                //读取资源文件,并将其写入到OutputStream字节流中;
                Client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
        }
    }

    简单的说一下这一块:
    先是定义了服务器的端口port(8888)和基目录webroot(resource),然后利用ServerSocket建立了一个本机上8888端口的服务器。为了完成要求5)支持多用户并发访问,我们在这边做了两件事,首先用一个while循环不断地监听是否有对应本服务器的请求,第二件事对于每一个请求访问的ip地址,新建一个线程与其进行交互。所以while里边就是利用新建一个socket并且让他WebServer.accept()去监听别人的请求,没听到就阻塞在这里一直监听,听到了new一个我们写好的线程HttpConnectThread并且start它。

    再来看看这个线程的run函数。首先利用socket的getInputStream()和getOutputStream()从Socket对象中获取InputStream和OutputStream字节流,这两个流分别对应request请求和response响应。request处理请求主要工作为读取InputStream字节流信息,转成字符串形式,并解析。Response处理响应会根据解析出来的信息,从WEB_ROOT目录中寻找请求的资源文件,读取资源文件,并将其写入到OutputStream字节流中。需要说明的是这里我使用if(request.parse(Client)==1)这句话是因为这里出现的一个小bug,后边我在说明request类再详细说明。

    (2)请求类

    //request.java
    package homework3;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.PrintStream;
    import java.net.Socket;  
    
    public class Request {  
        private InputStream input;  
        private String uri;  
    
        public Request(InputStream input){  
            this.input=input;  
        }  
    
        public int parse(Socket socket){  
            //Read a set of characters from the socket  
            StringBuffer request=new StringBuffer(2048);  
            int i;  
            byte[] buffer=new byte[2048];  
            try {  
                i=input.read(buffer);  
            } catch (Exception e) {  
                e.printStackTrace();  
                i=-1;  
            }  
            for(int j=0;j<i;j++){  
                request.append((char)buffer[j]);  
            }  
            System.out.print(request.toString());  
            uri=parseUri(request.toString()); 
    
    
            if(request.toString().split("\n")[0].contains("html")||request.toString().split("\n")[0].contains("jpg")){  
                return 1;
            }
            else{
                // 下面是由服务器直接生成的主页内容
                // 1、首先向浏览器输出响应头信息
                PrintStream out;
                try {
                    out = new PrintStream(socket.getOutputStream(), false, "GB2312");
    
                    out.println("HTTP/1.1 200\r"); 
                    out.println("Content_Type:text/html\r");
                    out.println("");//报文头和信息之间要空一行
                    // 2、输出主页信息
                    out.println(
    "<HTML><BODY>"
    + "<center>"
    + "<H1>HTTP协议测试服务器"
    + "</H1>"
    + "<form method='get' action='http://127.0.0.1:8888/'>username:<input type='text' name='username'/>password:<input type='text' name='password'/><input type='submit' value='GET测试'/></form><br/>"
    + "<form method='post' enctype='text/plain' action='http://127.0.0.1:8888/'>username:<input type='text' name='username'/>password:<input type='text' name='password'/><input type='submit' value='POST测试'/></form><br/>"
    + "</center>您提交的数据如下:<pre>" + request.toString()
    + "</pre></BODY></HTML>");
                    out.flush();
                    out.close();    
                    System.out.println("msg.toString()   "+request.toString());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    
            return 1;
    
        }  
    
        public 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 this.uri;  
        }  
    }

    这个程序我调了很久的bug,因为本来并没有写html文件,而是像上边程序中一样直接通过printStream输出流往socket的getOutputStream输出html语句就可以出现对应的网页,但是在显示图片的时候出现了坑爹的情况。首先使用绝对路径的时候浏览器会报错“Not allowed to load local resource”,究其原因是浏览器基于安全考虑不允许直接访问。换成相对路径吧,服务器当前工作路径下建一个resource放图片,写地址用/resource/xxx.jpg。好么,图片死活不出来,在浏览器按F12审查了半天也没审查个所以然来,感觉就是传过去的文件type是text/html类型的而不是jpg类型的(但是最后改完可以显示了我一看还是text/html类型),总之经历了很久debug的绝望以后我换成了现在这种写法,即要显示图片的话还是老老实实写一个html页面,如果是动态显示记录的浏览器与服务的交互过程(是的本程序你不知可以在console里看,在浏览器也可以直接看),没涉及图片输出,用我原来的想法。这就解释了我为什么要把require返回给服务器的return分为1和0了,解析报文如果有请求图片和html文件,那么返回1,调用response回应对应文件,否则返回0不调用response的内容,而是直接通过printStream输出html语句动态显示get和post过程中的报文协议。

    (3)回应请求类

    //response.Java
    package homework3;
    
    import java.io.File;  
    import java.io.FileInputStream;  
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.PrintStream;
    import java.net.Socket;  
    
    /** 
     * HTTP Response = Status-Line 
     *      *(( general-header | response-header | entity-header ) CRLF)  
     *      CRLF 
     *      [message-body] 
     *      Status-Line=Http-Version SP Status-Code SP Reason-Phrase CRLF 
     * 
     */  
    public class Response {  
        private static final int BUFFER_SIZE=1024*1024;  
        Request request;  
        OutputStream output;  
    
        public Response(OutputStream output){  
            this.output=output;  
        }  
    
        public void setRequest(Request request){  
            this.request=request;  
        }  
    
        public void sendStaticResource(Socket socket)throws IOException{  
            byte[] bytes=new byte[BUFFER_SIZE];  
            FileInputStream fis=null;  
            try { 
                    File file=new File(MyWebServer.WEB_ROOT,request.getUri());
                    if(file.exists()){ 
    
                        fis=new FileInputStream(file);  
                        int ch=fis.read(bytes,0,BUFFER_SIZE); 
                        String header = "HTTP/1.1 200\r\n" + "Content-Type: text/html\r\n"+ 
                                "Content-Length: " + file.length() + "\r\n" + "\r\n";
                        output.write(header.getBytes());
                        while(ch!=-1){  
    
                            output.write(bytes, 0, BUFFER_SIZE);  
                            ch=fis.read(bytes, 0, BUFFER_SIZE);  
                        }
    
                    }else{  
                        //file not found  
                        String errorMessage="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(errorMessage.getBytes());  
                    }  
            } catch (Exception e) {  
                System.out.println(e.toString());  
            }finally{  
                if(fis!=null){
                    output.close();
                    fis.close();  
                }  
            }  
        }  
    }

    (2)(3)两个类就不详细一句句说明了,就着注释应该很容易明白。

    三.实现效果

    点开MyWebServer文件,点击运行,console会跳出:
    这里写图片描述
    随便打开一个浏览器(我用的是chrome),输入127.0.0.1:8888
    这里写图片描述
    在get和post随便输入数据点击按钮,可以观察下边的数据变化情况
    OK~如果想要访问图片和服务器里的html文件,输入127.0.0.1:8888/index.html
    这里写图片描述
    根据页面内容点击链接可以访问不同的文件。当然回头看一下console里面记录着所有的protocol信息。
    这里写图片描述
    这里写图片描述
    最后附上index.html和index2.html(图片大家自己找啦)

    <!DOCTYPE html>  
    <html>  
    <head>  
    <meta charset="UTF-8">  
    <title>Web服务器</title>  
    </head>  
    <body>  
        <h1>This is yaozonghai's webserver</h1>
        <img src="pic\a3.jpg" /><br>
        <h5>This is a simple index.Your request will be sent to my WebServer</h5>
        <p>you can click <a href="index2.html"> more image</a> to scan picture on web<p>
        <img src="pic\a5.jpg" /><br>
        <p>you can click <a href="xxx"> observe the http protocol</a> to observe the http protocol<p>
        <h3>Thank you for using<h3>
    </body>  
    </html>  
    <!DOCTYPE html>  
    <html>  
    <head>  
    <meta charset="UTF-8">  
    <title>LBJ</title>  
    </head>  
    <body>  
        <h1>so handsome the man is</h1> 
        <img src="pic\a1.jpg" />
        <img src="pic\a2.jpg" />
        <img src="pic\a3.jpg" />
        <img src="pic\a4.jpg" />
        <a href="index.html"> 返回</a>
    
    </body>  
    </html>  

    That’s all,thank you!

    展开全文
  • Web安全编程

    千次阅读 2015-05-12 20:49:32
    安全编程能够体现一个程序员是否合格,什么是安全编程,就是在开发阶段避免系统漏洞,根据乌云漏洞平台的统计,2014排行前10的安全问题如下: 最容易由程序员的编程疏忽产生的漏洞是SQL注入和XSS,SQL注入的危害...

    安全编程能够体现一个程序员是否合格,什么是安全编程,就是在开发阶段避免系统漏洞,根据乌云漏洞平台的统计,2014排行前10的安全问题如下:


    SQL注入攻击:

    最容易由程序员的编程疏忽产生的漏洞是SQL注入和XSS,SQL注入的危害严重的情况是泄漏整个数据库的信息,后果不堪设想,XSS的后果严重的情况使用户信息泄漏。以MyBatis为例如何防止SQL注入,如下一条查询语句:

    SELECT * from answer a where a.username=#{username}

    还可以换个方法写:

    SELECT * from user u where u.username='${username}'
    在MyBatis里对SQL的处理分为两种,一种是DynamicSqlSource,用于动态的拼接SQL,还有一种是RawSqlSource,静态的SQL(已经预编译)。

    MyBatis对#{}的处理就是静态预编译,将SQL参数化,假设用户传的username我们没有过滤,直接用,如果输入的是“ vince' or '1' == '1 ”,预计编译的处理会对特定的字符做转义,数据库会去匹配整个字符串,但${}的处理则是拼接成一个新的SQL,拼接后的SQL如下:

    SELECT * from user u where u.username='vince' or '1' == '1'

    是不是结果就不是我们预期的了,严重的情况会使整个数据库被攻破,防止SQL注入的方法有很多,对用户输入的参数进行严格的校验同样也能避免此类问题,不过数据库在设计之初已经帮我们想好了处理方案,就是SQL的预编译,不仅提高执行效率,而且能够防止SQL注入。

    跨站脚本攻击:

    跨站脚本攻击也是一个开发人员引起的软件漏洞,开发人员没有对展示的文本进行转义处理,导致用户上传的恶意脚本在浏览器中执行了,这也叫代码注入,开发人员也可以通过严格的参数校验和过滤进行避免,也可以利用工具处理,例如Freemarker模板框架里的freemarker.template.utility.StringUtil.XMLEncNA(String),

    用户输入的内容是 <script>alert('hel');</script>  处理后变成了 &lt;script&gt;alert('hel');&lt;/script&gt;  这样浏览器就不会执行这段脚本,但最终在浏览器上还是展示成 <script>alert('hel');</script>  ,试想一下,如果这里不是alert一个字符串,而是引入一个外部的JS文件,这个文件里的操作是获取用户的Cookie,Cookie里可能包含了某个网站的有效会话SessionID,然后将获取到的数据发到某个邮箱里,恶意的人可以用这个会话登录这个网站,后果可想而知了。

    尤其是在有文件上传,用户输入框的地方,开发人员一定要有严格的防范意识,不要依赖客户端JS上的验证,任何用户输入的校验都要验证两次,至少服务器要校验一次。

    有一个组织www.owasp.org/   在web安全方面做的很好,公益性的,贡献了很多资料值得我们开发人员学习。

    2013年排名前10的安全漏洞

    安全测试指南

    安全编码规范

    其他安全注意事项:

    还有很多容易引起安全漏洞的不良编码习惯,例如对密码的不重视,在软件中留SQL后门等等,当然不是所有漏洞都是开发人员引起的


    展开全文
  • 所有编程皆为Web编程

    万次阅读 多人点赞 2014-04-27 09:33:14
    桌面应用软件已经完蛋了!!!几年来,大部分桌面应用软件都被Web应用代替了。随着网络浏览器进化得越来越强大和健壮,每天都有更多的桌面应用被取代。
  • 用NoWEB进行文学编程

    千次阅读 2015-04-09 18:05:14
    首先有CWEB工具是为c语言设计web程序, 后又有为fortran设计web。 在pyhton中有leo既是IDE又是文章编程工具, 但是对ide我一向推崇emacs, 故也不可用。 找到三个语言无关的web,fuweb, n
  • [Web]Web编程语言 之 我选择我喜欢

    千次阅读 2006-12-22 12:28:00
    1. Python+Web这几天就憋在房子里搞Web编程,进行语言的选择、框架的选择,把头弄得都晕了。因为对Python比较熟悉,先看Python下进行Web编程如何。Python下的Web框架是最多的,越多就越不容易挑选,你要对每种框架...
  • web编程课程小结

    千次阅读 2016-12-21 21:31:24
    本学期学习了网络编程课程,但是并没有涉及到socket等内容,所以准确来说应该算是web编程课,以下是对本学期课程学习要点的一些总结: html/css (1)学习了常用的一些简单标签,然后制作了单列布局(仅使用了html...
  • Android Web应用高级编程

    千次阅读 2012-05-14 08:53:06
    基本信息 原书名: Pro Android Web Apps: Develop for Android using HTML5, CSS3 & JavaScript 原出版社: Apress 作者: (美)Damon ...丛书名: 移动嵌入式开发技术 出版社:清华大学出版社 ISBN:
  • JAVA_web 编程实战、编程步骤

    千次阅读 2018-03-12 17:44:16
    编程实战  通讯录程序 软件的生命周期 3.1 需求分析(需求分析师) 功能分析: 1)添加联系人 2)修改联系人 3)删除联系人 4)查询所有联系人 功能流转  美工设计设计...
  • Web 2.0 编程思想

    千次阅读 2006-04-04 23:04:00
    无论你是一个Web 2.0应用的创建者还是用户,请清晰的构思你的目标。就像“我需要保存一个书签”或者“我准备帮助人们创建可编辑的、共享的页面”这样的目标,让你保持最 基础的需求。很多Web 2.0应用的最初吸引之处...
  • 我们基本每天都在通过WEB浏览器,去浏览一些新闻,看看...那顺道就来简单的看一下,所谓的Web服务器(例如知名的Tomcat)浏览器,基本的实现原理是什么样的呢? 首先可以明确的就是,例如我们所做的通过浏览器输入一
  • 2020年 Web 开发的最佳编程语言

    千次阅读 2020-04-22 21:38:44
    现在最需要的技能之一是编写编程代码的专业知识。以计算机为基础的智能,ML和区块链看起来是本世纪压倒一切的潜在竞争者。Web计划和改进是最重要的吸引人的领域,也是许多新的爆破模式的建立。
  • 用于Web开发的最佳编程语言

    千次阅读 2018-11-05 19:44:19
    用于Web开发的最佳编程语言
  • Web 设计与开发终极资源大全(上)

    千次阅读 热门讨论 2010-03-18 12:01:00
    Web 技术突飞猛进,Web 设计与开发者们可以选择的工具越来越多,Web 开发者的技巧不再只限于 HTML 和 服务器端编程,还需要精通各种第三方资源,这些第三方资源有时候比你的项目更复杂,更专业,你无法自己实现一切...
  • Java web编程(一)

    千次阅读 2018-07-23 14:04:35
    1、web 是一种基于超文本和http的、全球...2、web应用是多个web资源的集合,是供浏览器访问的程序 web应用包含的内容:静态、动态 静态部分 HTML页面 css样式 JavaScript脚本 b...
  • Web 设计与开发终极资源大全(下)

    千次阅读 热门讨论 2010-03-18 13:29:00
    Web 技术突飞猛进,Web 设计与开发者们可以选择的工具越来越多,Web 开发者的技巧不再只限于 HTML 和 服务器端编程,还需要精通各种第三方资源,这些第三方资源有时候比你的项目更复杂,更专业,你无法自己实现一切...
  • 基于Web在线考试系统的设计与实现

    万次阅读 多人点赞 2015-12-16 17:39:29
    这是一个课程设计的文档,源码及文档数据库我都修改过了,貌似这里复制过来的时候图片不能贴出 ...提取码:erzt 数据库原理课程设计说明书 ...1课题背景意义.3 1.1课题开发背景.3 1.2课题开发意义.3 2系...
  • Web编程期末大作业

    千次阅读 2020-06-30 12:09:09
    大作业要求 准备阶段 刚开始什么都没做,直接打开网页,发现和老师展示的效果大相径庭,之后了解到要先npm start进行启动,接下来的一系列结果就更傻眼了。。。 他先说我少了nodejieba这个安装包,好的,我这就去安...
  • 树莓派WEB服务器(Boa)CGI编程入门

    千次阅读 2017-07-20 18:06:22
    通过上一个课程“Boa基本设置使用”的学习... 下面通过一个CGI编程实例来学习,WEB服务器的动态编程技术。“体重指数(BMI)计算器”,用户输入自己的身高体重后点击计算,服务器就会计算出BMI数值。 课程资源(程
  • Web 设计与开发者必须知道的 15 个站点

    千次阅读 热门讨论 2009-07-24 17:09:00
    工作期间,常用到一些工具帮助站点,今天读到一篇文章,介绍了15个对 Web设计与开发师极端有用的站点,里面有不少也是我们一直在使用的,也许对很多人都有用,翻译出来以饷同仁。ColorCombos配色是 Web 设计的首要...
  • 使用Java实现Web服务器编程

    千次阅读 2018-06-09 12:35:41
    import java.io.*;import java.net.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*;...public class WebServer { public static void main(String[...
  • 关于初学者要怎么样学习WEB编程

    千次阅读 2011-09-11 12:51:34
    最近很多人在WEB编程开发这个版块发表帖子,例如"我是初学者,我应该从哪里开始学习","我的某方面不好,对WEB编程有没有影响","学习WEB编程的话要从什么地方写起,ASP ASP.NET PHP JAVA 先学哪个,后学哪个."等等,...
  • 简单web服务器的设计与实现

    万次阅读 2017-01-27 19:48:09
    socket web服务器
  • 上代码 运行完打开浏览器访问127.0.0.1:8000 #include &amp;lt;cstdio&amp;gt; #include &amp;lt;string&amp;gt; #include &amp;lt;fstream&amp;gt; #include &amp;...
  • WEB 开发Java框架及设计模式

    千次阅读 2010-08-01 15:56:00
    这节课分三个小节,分别是WEB原理,JAVAEE框架,设计模式 首先我们要明白Web的概念,以及原理是什么。 大家,对于web并不陌生,我们平时上网浏览的 新浪,网易就是一个Web站点,他们都是靠提供...
  • Web前端是互联网时代软件产品研发中不可缺少的...从广义上来讲,所有用户终端产品视觉和交互有关的部分,都是Web前端工程师的专业领域。 就目前Web前端开发可能涉及的语言来讲,有PHP语言、JavaScript、Ruby、HTML...
  • Brython被用来设计为替代JavaScript,用于Web客户端编程。它是一个浏览器上的Python 3实现,支持HTML5环境(提供了DOM对象和事件接口)。在Demo网站上(http://www.brython.info/)显示了一个HTML5动态时钟,不过...
  • 内容相关: 1、 网络基本原理(如:HTTP协议、Web服务器、Socket、TCP、...3、程序设计(socket编程、多线程程序设计等) JAVA代码: MultiThreadWebServer.java import java.net.* ; public final class Multi
  • Web编程技术》学习笔记(一)

    千次阅读 2019-03-21 20:18:20
    一、WEB编程基础知识 统一资源定位符(URL)(互联网的一个协议要素,定义任何远程或本地的可用资源) 其通用格式为:协议:[//][[用户名[:密码]@]主机名[:端口号]][/资源路径] 二、WEB编程主流技术 Web是典型的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 393,405
精华内容 157,362
关键字:

web设计与编程