前端时间,用线程池做了一个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服务器,实现基本的http 协议get和post方法
基于Http客户端服务器Demo,服务器是轻量级的HTTP框架,客户端有用到线程池哦,记得是跑在linux环境上的,打开压缩包,会有一个server,client文件夹,本来一个make就可以编译运行demo,但是代码是我的IP,所以亲爱的您...
基于java线程池、java Socket实现了一个简单的多线程Http服务器,可以实现GET资源获取功能、GET表单提交功能,POST 表单提交功能、单文件上传功能。
**本项目实现了基于Epoll管理连接、基于定时器处理非活动连接、基于线程池实现Reactor模式、基于cgi脚本处理http请求结果的HTTP服务器。主要框架如下:**\ ![](./image/newhttpd.jpg) 2、模块介绍 **1)主线程...
基于普通线程池的处理模式,也存在队列阻塞的问题——若干个客户端请求的耗时操作,阻塞了其他客户端的响应,哪怕其他客户端的请求很短时间就能处理完毕,也必须排队等待。采用流水线线程池避免了这个问题。每个...
设计模式、TCP高并发服务器、HTTP连接、DNS查询、DNS异步I/O查询实现、多线程实现、线程池实现、MySql使用、MySql连接池实现、通讯录实现。
1.利用IO多路复用技术Epoll与线程池实现Reactor高并发模型。 2.利用主从状态机解析HTTP请求报文,实现对资源的请求。 3.使用升序双向链表实现定时器,关闭超时的非活动连接。 4.单例模式的日志系统,实现异步写入...
(牛客网C++课程)Linux 高并发Web服务器项目实战(带定时检测代码) 技术框架: 1. 线程池 + 非阻塞 socket + epoll + 事件处理的并发模型 2. 状态机解析HTTP请求 3. 心跳机制 4. 简易日志系统 主要内容: 1. ...
之上的简单Http服务器和客户端 美丽是之上的一层,它提供了创建Http服务器或客户端的工具。 Beauty允许创建同步或异步服务器和客户端,并基于添加一些信号和计时器管理 特征 Http或Http / s服务器或客户端 同步或...
实现功能:基于HTTP协议,解析请求和拼接响应,基于NIO的非阻塞,线程池,文件传输。代码有详细注释和清晰的框架。 程序入口是: /HttpServerReactor/src/com/StartServer.Java 访问1,浏览:...
Linux下基于C++的轻量级Web服务器; (1)使用 线程池 + 非阻塞socket + epoll(ET和LT均实现) + 事件处理(Reactor、Proactor) 的并发模型; (2)使用状态机解析HTTP请求报文,支持解析GET和POST请求; (3)访问...
基于c++及linux网络编程的web服务器源码.zip 基于c++及linux网络编程的web服务器 该web服务器的主要内容如下: 使用了epoll边沿触发+EPOLLONESHOT+非阻塞IO 使用了一个固定线程数的线程池 实现了一个任务队列,...
*支持基于线程池的异步读写sqlite3数据库; *支持ARM体系结构; *提供方便的轻量级ORM实现,支持常规的对象到数据库双向映射; *支持可在加载时由配置文件安装的插件; *通过内置连接点支持AOP。
基于C++实现的轻量级Web服务器源码+项目说明.zip 开发部署环境 操作系统: Ubuntu 16.04 编译器: g++ 5.4 版本控制: git 自动化构建: cmake 集成开发工具: CLion 编辑器: Vim 压测工具:WebBench 核心功能及...
使用TCPServer编写(多线程)socket服务 http://blog.csdn.net/ghostfromheaven/article/details/8653421
利用IO复用技术Epoll与线程池实现多线程的Reactor高并发模型; 利用正则与状态机解析HTTP请求报文,实现处理静态资源的请求; 利用标准库容器封装char,实现自动增长的缓冲区; 基于小根堆实现的定时器,关闭超时...
- 为充分利用多核CPU的性能,以多线程的形式实现服务器,并实现线程池避免线程频繁创建销毁造成的系统开销 - 实现基于小根堆的定时器,用于断开超时连接 - 实现可以自动增长的缓冲区,作为HTTP连接的输入和输出缓冲...
15.5 半同步半反应堆线程池实现 15.6 用线程池实现的简单Web服务器 15.6.1 http_conn类 15.6.2 main函数 第三篇 高性能服务器优化与监测第16章 服务器调制、调试和测试 16.1 最大文件描述符数 16.2 调整内核...
bas为boost_asio_server(baserver)的简称,是采用...5、提供echo_server/echo_client、ssl_server/ssl_client、proxy_server、http_server(基于asio的http server示例)等示例供参考。 请使用svn checkout最新的代码。
完整的vs2015工程,基于mongoose的http服务器,使用线程池技术实现word转pdf和word比较的多任务处理