前端时间,用线程池做了一个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请求。 首先,让我们深入了解线程池的概念。线程池是由多个工作线程组成的集合,这些线程共享一个任务队列。当有...
本实验项目“基于线程池的WebServer”旨在实现一个高效、可扩展的Web服务,通过利用线程池来处理并发请求,提高系统的响应速度和吞吐量。 线程池的核心思想是预先创建并维护一组线程,而不是每次有任务时都创建新的...
1. Spring提供了一个名为ThreadPoolTaskExecutor的实现,它基于Java的ExecutorService接口,允许我们自定义线程池配置,如核心线程数、最大线程数、队列容量、超时时间等。 2. 通过在配置文件中声明一个...
基于线程池的 HTTP 服务器实现 本次实验报告的主要内容是关于基于线程池的 HTTP 服务器的实现,旨在解决传统 HTTP 服务器在单线程环境下频繁创建线程、销毁线程、请求的接收和处理必须严格同步的缺陷。实验报告从...
这个Web服务器的实现是基于Linux内核提供的异步I/O模型,Epoll,以及线程池策略,以优化系统资源的使用和提高并发性能。 首先,让我们理解Epoll(Event Poll)是什么。Epoll是Linux内核提供的一种I/O多路复用技术,...
利用线程池技术,爬虫程序可以在接收到爬取任务后立即并发执行,减少了等待服务器响应的平均时间。同时,线程池还提供了统一的任务调度平台,允许线程池对线程进行有效的管理和调度。 在设计上,线程池主体部分负责...
基于Http客户端服务器Demo,服务器是轻量级的HTTP框架,客户端有用到线程池哦,记得是跑在linux环境上的,打开压缩包,会有一个server,client文件夹,本来一个make就可以编译运行demo,但是代码是我的IP,所以亲爱的您...
本项目是基于C++实现的一个简单的HTTP服务器,它利用了线程池和Reactor模式,这两种技术在现代网络编程中具有重要的地位。 **HTTP服务器基础** HTTP(超文本传输协议)是互联网上应用最广泛的一种网络协议,用于从...
HTTP服务器是互联网上服务端应用的核心,用于接收客户端(如浏览器)发送的HTTP请求,并返回相应的HTTP响应。HTTP协议基于TCP/IP通信协议,是无状态的,即每次请求与响应之间不保留任何上下文信息。常见的HTTP服务器...
**本项目实现了基于Epoll管理连接、基于定时器处理非活动连接、基于线程池实现Reactor模式、基于cgi脚本处理http请求结果的HTTP服务器。主要框架如下:**\ ![](./image/newhttpd.jpg) 2、模块介绍 **1)主线程...
1. **基于线程池的HTTP服务器**:由于单进程无法同时处理多个连接,多进程又过于消耗资源,因此采用多线程模型。线程池预先创建一定数量的线程,当有新的连接请求时,主线程将任务加入线程池的任务队列,由空闲线程...
在Linux操作系统中,开发一款多线程轻量级HTTP服务器是一项技术挑战,它涉及到网络编程、多线程处理以及对HTTP协议的理解。本项目“Linux下多线程轻量级HTTP服务器”旨在实现一个基本的HTTP服务器,能够响应客户端的...
总结来说,一个高效的Tomcat服务器需要合理配置其连接器的协议类型、连接数和线程池大小。通过选择合适的协议,优化连接处理方式,合理分配线程资源,可以显著提升Tomcat服务器在处理并发请求时的性能。同时,需要...
【标题】"HTTP-Server:具有线程池的http服务器实现"揭示了这是一个基于C语言编写的HTTP服务器项目,其核心特性是利用线程池来处理客户端请求。线程池是一种多线程处理形式,预先创建了一组线程,当有任务需要执行时...
对比JDK的ExecutorService,Tomcat的线程池在设计上更注重Web服务器的特定需求,如快速响应HTTP请求和良好的监控能力。例如,Tomcat线程池提供了详细的MBean接口,允许管理员在运行时监控和调整线程池的状态,这对于...
本项目“基于Java线程池技术的数据爬虫设计与实现”关注的是如何利用Java编程语言,结合线程池技术来高效地构建数据爬虫。线程池作为一种资源管理策略,能够有效地减少创建和销毁线程的开销,提高系统资源利用率,是...
HTTP协议是基于TCP/IP的,因此在C#实现的HTTP服务器中,TCP协议的处理是基础。TCP确保数据的可靠传输,通过三次握手建立连接,四次挥手断开连接。在C#中,TcpClient和TcpListener类可以方便地管理TCP连接。 接下来...
标题中的“一个用C语言写的高并发http服务器,线程池,epoll,通用数据结构,事件触发.zip”表明这是一个基于C语言实现的高性能HTTP服务器,它利用了线程池、epoll(边缘触发I/O多路复用)以及一些通用的数据结构来处理...
在Python开发中,网络编程是实现各种网络服务的基础,如HTTP服务器、聊天室应用等。在给定的“Python-基于socket的MVC服务器框架”中,我们可以深入探讨如何使用Python的socket库来构建一个简单但功能完备的MVC...
本文将深入探讨采用C++实现的异步HTTP服务器程序代码,旨在帮助开发者理解和掌握HTTP服务器的设计原理与实践技巧。 首先,我们要了解什么是异步HTTP服务器。传统的同步HTTP服务器在接收到客户端请求后会阻塞等待...