`

一个简单的异步Http连接器

    博客分类:
  • java
阅读更多

      前两天看了Tomcat连接器部分的源码,Tomcat 4默认的连接器随意已经过时了,但是是一个很好的学习工具。它里面用了多线程的机制使得HttpProcesor异步处理。我但是也是看了很长时间,最后大部分看懂了,但是还有很多没有看懂。我自己写了一个很简单的一个连接器HttpConnector,一个HttpProcessor,帮助大家理解它,先看看程序吧。


BootStrap类很简单,就是使得HttpConnector监听socket请求,这个很好理解。

public class BootStrap {
	public static void main(String[] args){
		HttpConnector connector = new HttpConnector();
		connector.start();
		System.out.println("Server is started, listened in 9999!");
	}
}


    下面是一个比较复杂的HttpConnector类,它首先会创建ServerSocket,然后启动线程,创建minProcessors个HttpProcesor,并使它们都启动起来。

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Stack;


public class HttpConnector implements Runnable{
	private ServerSocket serverSocket;
	
	private int minProcessors = 1;
	
	private int maxProcessors = 5;
	
	private int curProcessors = 0;
	
	private Stack<HttpProcessor> processors = new Stack<HttpProcessor>();
	
	private boolean stopped = false;
	
	public void run() {
		try {
			while(!stopped){
				Socket socket = serverSocket.accept();
				
				HttpProcessor processor = createProcessor();
				
				if(processor != null) {
					processor.assign(socket);
				} else {
					System.out.println("Socket is no resource to be handled!");
				}
				
				socket.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void recycle(HttpProcessor processor){
		processors.push(processor);
	}
	
	public void start(){
		try {
			serverSocket = new ServerSocket(9999);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		Thread thread = new Thread(this);
		thread.start();
		
		while(curProcessors < minProcessors){
			if(maxProcessors > 0 && curProcessors >= maxProcessors){
				break;
			}
			HttpProcessor processor = newProcessor();
			processors.push(processor);
		}
	}

	private HttpProcessor newProcessor() {
		HttpProcessor processor = new HttpProcessor(this,curProcessors++);
		processor.start();
		return processor;
	}
	
	private HttpProcessor createProcessor(){
		synchronized(processors){
			if(processors.size() > 0){
				return processors.pop();
			} else {
				if(maxProcessors > 0 && curProcessors < maxProcessors){
					return newProcessor();
				} else {
					if(maxProcessors < 0){
						return newProcessor();
					} else {
						return null;
					}
				}
			}
		}
	}
	
}


      下来一个是HttpProcessor,在线程启动后,会调用await方法,使得当前线程等待,有个Socket请求来临之后,调用assign方法,使得当前线程继续运行,但是assign方法会返回,HttpConnector就可以继续相应请求了。在HttpProcessor处理完了之后,HttpPrcoessor会重新放到栈中,就可以进行复用了。这个来的线程同步感觉看了很久还是明白了,但是我估计
现在还写不出来。

import java.net.Socket;


public class HttpProcessor implements Runnable{
	private HttpConnector connector;
	
	private int processorId;
	
	private Socket socket;
	
	private boolean avaliable = false;
	
	private boolean stopped = false;
	
	public HttpProcessor(HttpConnector connector, int processorId){
		this.connector = connector;
		this.processorId = processorId;
	}
	
	public void run(){
		while(!stopped){
			Socket socket = await();
			
			process(socket);
			
			connector.recycle(this);	
		}
	}
	
	public void process(Socket socket){
		System.out.println("Processor " + processorId + " Process socket :" + socket.getPort());
	}
	
	public void start(){
		Thread thread = new Thread(this);
		thread.start();
	}
	
	public synchronized Socket await(){
		while(!avaliable){
			try {
				System.out.println("Process " + processorId + " is ready!");
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		avaliable = false;
		Socket socket = this.socket;
		notifyAll();
		return socket;
	}
	
	public synchronized void assign(Socket socket){
		while(avaliable){
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		avaliable = true;
		this.socket = socket;
		notifyAll();
	}
}


     最后贴上客户端程序,这个我们是来测试服务器端运行的,也很好理解。

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;


public class Client {
	public static void main(String[] args){
		for(int i = 0; i < 100; i++){
			Socket socket = null;
			try {
				socket = new Socket(InetAddress.getByName("127.0.0.1"),9999);
				System.out.println("Socket is started, socket id is:" + socket.getPort());
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

0
0
分享到:
评论

相关推荐

    socket异步连接——示例代码

    本文将重点介绍`Socket`的异步连接机制,并通过一个具体的C#示例来展示如何实现异步连接。 #### 二、Socket异步连接原理 在传统的同步通信模型中,客户端在发送请求后会等待服务器响应完成后再继续执行后续操作;而...

    Python-aiohttp一个用于asyncio和Python的异步HTTP客户端服务器

    Python的aiohttp库是为Python的异步IO框架asyncio设计的一个强大的工具,它集成了HTTP客户端和服务器的功能,使得在Python中处理网络请求变得高效且简洁。这个库允许开发者在同一时间处理多个网络连接,极大地提高了...

    (通用异步收发器)与蓝牙的接口连接

    本篇文章旨在探讨如何利用飞利浦UART(通用异步收发器)将蓝牙无线技术整合到一个系统中,特别关注于飞利浦UART如何作为蓝牙模块与主机系统之间的桥梁。 #### 二、蓝牙技术概述 蓝牙技术是一种短距离无线通信技术...

    Uart通用异步收发器

    Uart采用的是异步传输方式,这意味着在发送数据时并不需要同步时钟信号,而是依靠起始位和停止位来标识一个数据帧的开始和结束。一个完整的Uart数据帧通常包括: 1. **起始位**:一个低电平信号,表示数据传输的...

    tornado-redis:简单的异步 Tornado-redis 连接器

    **Tornado-Redis:异步Python Redis连接器** 在Python编程中,Tornado是一个流行的异步网络库,常用于构建高性能、可扩展的网络应用。而Tornado-Redis是专门为Tornado设计的一个轻量级、高效的Redis客户端,它充分...

    一个简单的异步网络通讯源代码.

    这个标题提到的“一个简单的异步网络通讯源代码”很可能是一个小型示例项目,用于展示如何实现这样的通信机制。接下来,我们将深入探讨异步网络通信的概念、其重要性以及可能的实现方式。 异步网络通信的核心在于非...

    异步通信核心简单实现(Java)

    本主题将深入探讨如何使用Java的非阻塞I/O(Non-blocking Input/Output,NIO)包来实现一个简单的异步通信核心,重点关注NIO中的通道(Channel)、通道选择器(Selector)和选择器键(Selector Key)。 1. **Java ...

    同步和异步串口

    异步传输是一种典型的基于字节的输入输出,指数据按每次一个字节进行传输,其传输速度较低。同步传输是把数据字节组合起来一起发送,这种组合称之为帧,其传输速度比异步传输快。 异步传输是指一次传输一个字符(5~...

    通用异步接收器发送器(Uart)中英文技术手册

    通用异步接收器发送器(UART)是一种广泛应用于嵌入式系统、计算机和其他电子设备中的串行通信接口。UART允许设备之间通过串行数据传输进行通信,即使它们使用不同的时钟速度。本技术手册将深入探讨UART的工作原理、...

    构建异步API服务

    EventMachine可以运行在MRI Ruby和其他Ruby解释器上,它提供了一个非常简单的方式来处理异步I/O操作,使得Ruby应用能够高效地处理大量的并发连接。Node.js,虽然不是Ruby环境,但它采用的事件驱动和非阻塞I/O模型在...

    ESP8266Arduino异步WEB服务库

    ESP8266Arduino异步WEB服务库是一个关键的开发工具,主要用于在基于ESP8266微控制器的Arduino项目中构建高效的Web服务器。ESP8266因其低廉的价格和强大的无线连接能力,已经成为物联网(IoT)项目中的热门选择。而这...

    异步电机矢量控制-仿真模型.rar

    4. **电源模型**:为了模拟电机与电网的连接,模型会包含一个交流电源模型,它可以模拟电网的电压波动和频率变化。 5. **接口模块**:这些模块用于输入和输出,例如设定电机速度、读取电机电流等。 6. **仿真设置*...

    tornado-asyntool:一个简单的工具让 tornadoweb 异步运行代码

    Tornado Web 是一个高度可定制、轻量级且性能优秀的异步Web服务器和框架,尤其适合处理大量的并发连接。而 Asyntool 就是这个框架的一个扩展,旨在进一步提升其在处理异步任务时的能力。 受 Tornado 自带的 ...

    用T'触发器74LS76构成的异步二进制减法计数器实验电路multisim源文件

    本文将深入探讨一个基于T'触发器74LS76构建的异步二进制减法计数器的实验电路,以及如何利用Multisim软件进行仿真验证。74LS76是一款经典的双D类型边沿触发T'(或非T)触发器集成电路,广泛应用于数字系统设计中。 ...

    MFC异步串口通信

    这可能是通过创建一个简单的控制台进程或使用`CreateProcess`函数来实现的,以便在命令行环境中观察通信效果。 总结起来,MFC异步串口通信是一种高效的方法,能够实现在不阻塞主线程的情况下进行串口交互。`...

    mina 同步客户端,异步客户端

    这种方式简单易懂,但效率较低,因为每个请求都需要占用一个线程直到响应返回。在MINA中,同步客户端通常使用`IoHandler`接口来处理事件,如连接建立、消息接收和断开连接。当客户端发送消息时,会阻塞直到接收到...

    三晶电气 KHAOS-S3100B异步伺服驱器简易说明书A3.zip

    【三晶电气 KHAOS-S3100B异步伺服驱动器简易说明书】是一部针对该型号伺服驱动器的专业指导文档,旨在帮助用户理解和操作三晶电气的KHAOS-S3100B异步伺服驱动器。此驱动器是工业自动化领域的关键设备,常用于精确...

    C# TCP助手异步通讯

    `TcpListener`是C#中的一个网络通信类,用于创建一个服务器端的TCP监听器,它可以监听特定的IP地址和端口,等待客户端的连接请求。创建`TcpListener`时,通常需要指定一个`IPHostEntry`对象和一个端口号。例如: ``...

    java异步server

    文件名"TcpClient.java"可能表示一个简单的TCP客户端示例。在Java中,`java.net.Socket`类用于创建TCP连接,客户端通常会创建一个Socket实例,指定服务器的IP地址和端口号,然后通过Socket进行数据的读写。 5. **...

Global site tag (gtag.js) - Google Analytics