`
sharp-fcc
  • 浏览: 106280 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

基于线程池的http服务器

阅读更多

     前端时间,用线程池做了一个http服务器,专门处理get请求,基于socket编程,主要是自己想对操作系统级的编程比较感兴趣。好了,贴出代码,供大家参考:

    

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try{
			
			ServerSocket server = new ServerSocket(8000);
			System.out.println("Server is listenning");

			ThreadPoolManager manager = new ThreadPoolManager(3);
			int  i = 0;
			while(true){
				
				Socket client = server.accept();
				manager.add(client);
				i++;
				System.out.println(i);
			
			}


		}catch(IOException e){
			e.printStackTrace();
		}
	}

  这是整个程序的入口,初始化该初始化的,监听该

监听的。ThreadPoolManager用于管理线程,初始化有三个线程。

     accept方法会造成阻塞,知道有消息传过来。将接收到的消息传入到manager中以便于管理。

   

 

 

public class ThreadPoolManager {
	private int maxThread;
	public Vector<SimpleThreak> vector;
	public Queue<Socket> buffer;
	public void setMaxThread(int maxThread) {
		this.maxThread = maxThread;
	}
	public int getMaxThread() {
		return maxThread;
	}
	
	public ThreadPoolManager(int threadCount){
		this.setMaxThread(threadCount);
		buffer = new ArrayBlockingQueue<Socket>(100);
		System.out.println("Starting pool");
		vector = new Vector<SimpleThreak>();
		for(int i=1;i<=threadCount;i++){
			SimpleThreak st = new SimpleThreak(i,buffer);
			vector.add(st);
			st.start();
		}
			
	}
	
	public void add(Socket client){
		synchronized (buffer) {
			buffer.offer(client);
			buffer.notify();
		}
		
		
	}
	

 

      线程池类,线程池在初始化之后放入一个vector之中,同时将请求放入一个缓冲区中,缓冲区用 ArrayBlockingQueue来做。

      BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会阻塞。ArrayBlockingQueue是对BlockingQueue的一个数组实现,它使用一把全局的锁并行对queue的读写操作,同时使用两个Condition阻塞容量为空时的取操作和容量满时的写操作。

 

    

	public synchronized void run(){
		try{
			
			while(true){
					    	synchronized (buffer) {
					    		
								if(buffer.isEmpty()){
									buffer.wait();
								}
								
								this.client = buffer.poll();
								System.out.println(this.number+"------running");
				    	
					    	}
			
				    		PrintStream outStream;
				    		BufferedReader in ;
							try {
								in = new BufferedReader(new InputStreamReader(client.getInputStream()));
								outStream = new PrintStream(new BufferedOutputStream(client.getOutputStream()));
								this.argument=in.readLine();
		
								if(getRequest(this.argument)){
									String fileName = getFileName(this.argument);
									File file = new File(fileName);
									if(file.exists()){
		
											sendFile(outStream,file);
										
									}else 
										System.out.println("不存在图片");
								}
								in.close();
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
					
							sleep(3*1000);
							//System.out.println("Thread is sleeping");
						
					}
			
		}catch(InterruptedException e){
			System.out.println("Interrupt");
		}
	}

   不断监视缓冲区中的动向,如果有了数据,就从缓冲区中取出socket,否则进入等待列,将socket封装到bufferReader中,取出请求的报文头,如果请求的文件存在,就将文件放入PrintStream中,送入客户端。为了看出效果,让线程工作完之后睡3秒钟。

  

 

   

	private String getFileName(String s){
		String f = s.substring(s.indexOf(' ')+1);
		f=f.substring(0,f.indexOf(' '));
		try{
			if(f.charAt(0)=='/')
				f=f.substring(1);
			
		}catch(StringIndexOutOfBoundsException e){
			e.printStackTrace();
		}
		
		if(f.equals("")) f = "index.html";
		return f;
		
	}

     通过截取报文头,来获取请求文件的位置。

 

 

 

	private void sendFile(PrintStream ps,File file){
		try{
			DataInputStream ds = new DataInputStream(new FileInputStream(file));
			int len = (int) file.length();
			//System.out.println(len);
			byte buf[]=new byte[len];
			ds.readFully(buf);
			ps.write(okResponse().getBytes());
			ps.write(buf,0,len);
			
			ps.flush();
			
			ds.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}

     将流传输到客户端的过程,先将数据写入到一个字节流中,输入到客户端。

  

     这样,一个简单的http服务器就完成了,服务器还有一个问题,就是请求过来之后会阻塞。从高人处得知,可以用nio这种非阻塞的io进行优化。正在研究之中。

 

 

分享到:
评论

相关推荐

    基于线程池web服务器

    基于线程池模拟web服务器,实现基本的http 协议get和post方法

    基于Http客户端服务器Demo,服务器是轻量级的HTTP框架,客户端有用到线程池哦

    基于Http客户端服务器Demo,服务器是轻量级的HTTP框架,客户端有用到线程池哦,记得是跑在linux环境上的,打开压缩包,会有一个server,client文件夹,本来一个make就可以编译运行demo,但是代码是我的IP,所以亲爱的您...

    java(简易)多线程HTTP服务器

    基于java线程池、java Socket实现了一个简单的多线程Http服务器,可以实现GET资源获取功能、GET表单提交功能,POST 表单提交功能、单文件上传功能。

    基于C++实现的HTTP服务器改进版源码+项目使用说明+详细注释.zip

    **本项目实现了基于Epoll管理连接、基于定时器处理非活动连接、基于线程池实现Reactor模式、基于cgi脚本处理http请求结果的HTTP服务器。主要框架如下:**\ ![](./image/newhttpd.jpg) 2、模块介绍 **1)主线程...

    基于Qt的多线程流水线异步服务器稳定版

    基于普通线程池的处理模式,也存在队列阻塞的问题——若干个客户端请求的耗时操作,阻塞了其他客户端的响应,哪怕其他客户端的请求很短时间就能处理完毕,也必须排队等待。采用流水线线程池避免了这个问题。每个...

    基于C语言实现多线程和线程池【100012227】

    设计模式、TCP高并发服务器、HTTP连接、DNS查询、DNS异步I/O查询实现、多线程实现、线程池实现、MySql使用、MySql连接池实现、通讯录实现。

    基于Linux的web服务器

    1.利用IO多路复用技术Epoll与线程池实现Reactor高并发模型。 2.利用主从状态机解析HTTP请求报文,实现对资源的请求。 3.使用升序双向链表实现定时器,关闭超时的非活动连接。 4.单例模式的日志系统,实现异步写入...

    (牛客网C++课程)Linux 高并发Web服务器项目实战(带定时检测代码)

    (牛客网C++课程)Linux 高并发Web服务器项目实战(带定时检测代码) 技术框架: 1. 线程池 + 非阻塞 socket + epoll + 事件处理的并发模型 2. 状态机解析HTTP请求 3. 心跳机制 4. 简易日志系统 主要内容: 1. ...

    beauty:Boost.Beast之上的一个简单的C ++ Http服务器客户端

    之上的简单Http服务器和客户端 美丽是之上的一层,它提供了创建Http服务器或客户端的工具。 Beauty允许创建同步或异步服务器和客户端,并基于添加一些信号和计时器管理 特征 Http或Http / s服务器或客户端 同步或...

    基于HTTP、NIO、多线程实现浏览器高并发非阻塞访问服务器文件

    实现功能:基于HTTP协议,解析请求和拼接响应,基于NIO的非阻塞,线程池,文件传输。代码有详细注释和清晰的框架。 程序入口是: /HttpServerReactor/src/com/StartServer.Java 访问1,浏览:...

    C++从零开始搭建一个web服务器

    Linux下基于C++的轻量级Web服务器; (1)使用 线程池 + 非阻塞socket + epoll(ET和LT均实现) + 事件处理(Reactor、Proactor) 的并发模型; (2)使用状态机解析HTTP请求报文,支持解析GET和POST请求; (3)访问...

    基于c++及linux网络编程的web服务器源码.zip

    基于c++及linux网络编程的web服务器源码.zip 基于c++及linux网络编程的web服务器 该web服务器的主要内容如下: 使用了epoll边沿触发+EPOLLONESHOT+非阻塞IO 使用了一个固定线程数的线程池 实现了一个任务队列,...

    基于C ++ 14/17的HTTP应用程序框架drogon.rar

    *支持基于线程池的异步读写sqlite3数据库; *支持ARM体系结构; *提供方便的轻量级ORM实现,支持常规的对象到数据库双向映射; *支持可在加载时由配置文件安装的插件; *通过内置连接点支持AOP。

    基于C++实现的轻量级Web服务器源码+项目说明.zip

    基于C++实现的轻量级Web服务器源码+项目说明.zip 开发部署环境 操作系统: Ubuntu 16.04 编译器: g++ 5.4 版本控制: git 自动化构建: cmake 集成开发工具: CLion 编辑器: Vim 压测工具:WebBench 核心功能及...

    使用TCPServer编写(多线程)socket服务

    使用TCPServer编写(多线程)socket服务 http://blog.csdn.net/ghostfromheaven/article/details/8653421

    C++ Linux WebServer服务器

    利用IO复用技术Epoll与线程池实现多线程的Reactor高并发模型; 利用正则与状态机解析HTTP请求报文,实现处理静态资源的请求; 利用标准库容器封装char,实现自动增长的缓冲区; 基于小根堆实现的定时器,关闭超时...

    SWINGS Web服务器

    - 为充分利用多核CPU的性能,以多线程的形式实现服务器,并实现线程池避免线程频繁创建销毁造成的系统开销 - 实现基于小根堆的定时器,用于断开超时连接 - 实现可以自动增长的缓冲区,作为HTTP连接的输入和输出缓冲...

    Linux高性能服务器编程

    15.5 半同步半反应堆线程池实现 15.6 用线程池实现的简单Web服务器 15.6.1 http_conn类 15.6.2 main函数 第三篇 高性能服务器优化与监测第16章 服务器调制、调试和测试 16.1 最大文件描述符数 16.2 调整内核...

    baserver服务器框架C++ Tcp server

    bas为boost_asio_server(baserver)的简称,是采用...5、提供echo_server/echo_client、ssl_server/ssl_client、proxy_server、http_server(基于asio的http server示例)等示例供参考。 请使用svn checkout最新的代码。

    mg_http_server.zip

    完整的vs2015工程,基于mongoose的http服务器,使用线程池技术实现word转pdf和word比较的多任务处理

Global site tag (gtag.js) - Google Analytics