`

基于Mina的Http Server以及简单的Http请求客户端

阅读更多
目的:
    Java平台下的内部组件之间的通信。
    1.WebService 由于感觉本身Java平台下的Web Service标准就不够统一,相互之间的调用就会有一些问题,更不用说与.net等其他平台了。而且WebService也是对HTTP请求的一次封装,效率上肯定会有损失,所以就不考虑用WebService了。
    2.Socket,包括Java原生的Socket API和nio,本身都很好,效率也会不错,它们之间的区别大概就是资源占用上了。但是使用Socket的通信,有几个比较复杂的地方是:1)协议解析,要订协议,解析及序列化2)粘包分包的处理(这个在长连接的情况下才会出现,可以不在考虑范围内)3)资源的管理,弄不好的话会导致CPU占用较高或者内存不知不觉泄露。
    3.HTTP通信。由于应用是独立的,不能依托于Web容器。Java原生的HttpServer API好像不推荐使用(藏在好深的一个包里com.sun.net.httpserver.*)。
    4.话说Mina的效率很高,是基于nio的异步通信,封装简化了好多。通过比较简单的包装就可以组成一个HTTP Server(下面例子中就是按照Mina官方提供的demo,自己改动了几点形成的)。然后HTTP的Client端也随便封装下就是了。

步骤
1.封装HTTP请求消息类和响应消息类
package com.ajita.httpserver;

import java.util.Map;
import java.util.Map.Entry;

/**
 * 使用Mina解析出的HTTP请求对象
 * 
 * @author Ajita
 * 
 */
public class HttpRequestMessage {
	/**
	 * HTTP请求的主要属性及内容
	 */
	private Map<String, String[]> headers = null;

	public Map<String, String[]> getHeaders() {
		return headers;
	}

	public void setHeaders(Map<String, String[]> headers) {
		this.headers = headers;
	}

	/**
	 * 获取HTTP请求的Context信息
	 */
	public String getContext() {
		String[] context = headers.get("Context");
		return context == null ? "" : context[0];
	}

	/**
	 * 根据属性名称获得属性值数组第一个值,用于在url中传递的参数
	 */
	public String getParameter(String name) {
		String[] param = headers.get("@".concat(name));
		return param == null ? "" : param[0];
	}

	/**
	 * 根据属性名称获得属性值,用于在url中传递的参数
	 */
	public String[] getParameters(String name) {
		String[] param = headers.get("@".concat(name));
		return param == null ? new String[] {} : param;
	}

	/**
	 * 根据属性名称获得属性值,用于请求的特征参数
	 */
	public String[] getHeader(String name) {
		return headers.get(name);
	}

	@Override
	public String toString() {
		StringBuilder str = new StringBuilder();

		for (Entry<String, String[]> e : headers.entrySet()) {
			str.append(e.getKey() + " : " + arrayToString(e.getValue(), ',')
					+ "\n");
		}
		return str.toString();
	}

	/**
	 * 静态方法,用来把一个字符串数组拼接成一个字符串
	 * 
	 * @param s要拼接的字符串数组
	 * @param sep数据元素之间的烦恼歌负
	 * @return 拼接成的字符串
	 */
	public static String arrayToString(String[] s, char sep) {
		if (s == null || s.length == 0) {
			return "";
		}
		StringBuffer buf = new StringBuffer();
		if (s != null) {
			for (int i = 0; i < s.length; i++) {
				if (i > 0) {
					buf.append(sep);
				}
				buf.append(s[i]);
			}
		}
		return buf.toString();
	}

}

package com.ajita.httpserver;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.mina.core.buffer.IoBuffer;

public class HttpResponseMessage {
	/** HTTP response codes */
	public static final int HTTP_STATUS_SUCCESS = 200;

	public static final int HTTP_STATUS_NOT_FOUND = 404;

	/** Map<String, String> */
	private final Map<String, String> headers = new HashMap<String, String>();

	/** Storage for body of HTTP response. */
	private final ByteArrayOutputStream body = new ByteArrayOutputStream(1024);

	private int responseCode = HTTP_STATUS_SUCCESS;

	public HttpResponseMessage() {
		// headers.put("Server", "HttpServer (" + Server.VERSION_STRING + ')');
		headers.put("Server", "HttpServer (" + "Mina 2.0" + ')');
		headers.put("Cache-Control", "private");
		headers.put("Content-Type", "text/html; charset=iso-8859-1");
		headers.put("Connection", "keep-alive");
		headers.put("Keep-Alive", "200");
		headers.put("Date", new SimpleDateFormat(
				"EEE, dd MMM yyyy HH:mm:ss zzz").format(new Date()));
		headers.put("Last-Modified", new SimpleDateFormat(
				"EEE, dd MMM yyyy HH:mm:ss zzz").format(new Date()));
	}

	public Map<String, String> getHeaders() {
		return headers;
	}

	public void setContentType(String contentType) {
		headers.put("Content-Type", contentType);
	}

	public void setResponseCode(int responseCode) {
		this.responseCode = responseCode;
	}

	public int getResponseCode() {
		return this.responseCode;
	}

	public void appendBody(byte[] b) {
		try {
			body.write(b);
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	public void appendBody(String s) {
		try {
			body.write(s.getBytes());
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	public IoBuffer getBody() {
		return IoBuffer.wrap(body.toByteArray());
	}

	public int getBodyLength() {
		return body.size();
	}

}

2.封装Mina的解析HTTP请求和发送HTTP响应的编码类和解码类
package com.ajita.httpserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.HashMap;
import java.util.Map;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.apache.mina.filter.codec.demux.MessageDecoderAdapter;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;

public class HttpRequestDecoder extends MessageDecoderAdapter {
	private static final byte[] CONTENT_LENGTH = new String("Content-Length:")
			.getBytes();
	static String defaultEncoding;
	private CharsetDecoder decoder;

	public CharsetDecoder getDecoder() {
		return decoder;
	}

	public void setEncoder(CharsetDecoder decoder) {
		this.decoder = decoder;
	}

	private HttpRequestMessage request = null;

	public HttpRequestDecoder() {
		decoder = Charset.forName(defaultEncoding).newDecoder();
	}

	public MessageDecoderResult decodable(IoSession session, IoBuffer in) {
		try {
			return messageComplete(in) ? MessageDecoderResult.OK
					: MessageDecoderResult.NEED_DATA;
		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return MessageDecoderResult.NOT_OK;
	}

	public MessageDecoderResult decode(IoSession session, IoBuffer in,
			ProtocolDecoderOutput out) throws Exception {
		HttpRequestMessage m = decodeBody(in);

		// Return NEED_DATA if the body is not fully read.
		if (m == null) {
			return MessageDecoderResult.NEED_DATA;
		}

		out.write(m);

		return MessageDecoderResult.OK;

	}

	/*
	 * 判断HTTP请求是否完整,若格式有错误直接抛出异常
	 */
	private boolean messageComplete(IoBuffer in) {
		int last = in.remaining() - 1;
		if (in.remaining() < 4) {
			return false;
		}

		// to speed up things we check if the Http request is a GET or POST
		if (in.get(0) == (byte) 'G' && in.get(1) == (byte) 'E'
				&& in.get(2) == (byte) 'T') {
			// Http GET request therefore the last 4 bytes should be 0x0D 0x0A
			// 0x0D 0x0A
			return in.get(last) == (byte) 0x0A
					&& in.get(last - 1) == (byte) 0x0D
					&& in.get(last - 2) == (byte) 0x0A
					&& in.get(last - 3) == (byte) 0x0D;
		} else if (in.get(0) == (byte) 'P' && in.get(1) == (byte) 'O'
				&& in.get(2) == (byte) 'S' && in.get(3) == (byte) 'T') {
			// Http POST request
			// first the position of the 0x0D 0x0A 0x0D 0x0A bytes
			int eoh = -1;
			for (int i = last; i > 2; i--) {
				if (in.get(i) == (byte) 0x0A && in.get(i - 1) == (byte) 0x0D
						&& in.get(i - 2) == (byte) 0x0A
						&& in.get(i - 3) == (byte) 0x0D) {
					eoh = i + 1;
					break;
				}
			}
			if (eoh == -1) {
				return false;
			}
			for (int i = 0; i < last; i++) {
				boolean found = false;
				for (int j = 0; j < CONTENT_LENGTH.length; j++) {
					if (in.get(i + j) != CONTENT_LENGTH[j]) {
						found = false;
						break;
					}
					found = true;
				}
				if (found) {
					// retrieve value from this position till next 0x0D 0x0A
					StringBuilder contentLength = new StringBuilder();
					for (int j = i + CONTENT_LENGTH.length; j < last; j++) {
						if (in.get(j) == 0x0D) {
							break;
						}
						contentLength.append(new String(
								new byte[] { in.get(j) }));
					}
					// if content-length worth of data has been received then
					// the message is complete
					return Integer.parseInt(contentLength.toString().trim())
							+ eoh == in.remaining();
				}
			}
		}

		// the message is not complete and we need more data
		return false;

	}

	private HttpRequestMessage decodeBody(IoBuffer in) {
		request = new HttpRequestMessage();
		try {
			request.setHeaders(parseRequest(new StringReader(in
					.getString(decoder))));
			return request;
		} catch (CharacterCodingException ex) {
			ex.printStackTrace();
		}

		return null;

	}

	private Map<String, String[]> parseRequest(StringReader is) {
		Map<String, String[]> map = new HashMap<String, String[]>();
		BufferedReader rdr = new BufferedReader(is);

		try {
			// Get request URL.
			String line = rdr.readLine();
			String[] url = line.split(" ");
			if (url.length < 3) {
				return map;
			}

			map.put("URI", new String[] { line });
			map.put("Method", new String[] { url[0].toUpperCase() });
			map.put("Context", new String[] { url[1].substring(1) });
			map.put("Protocol", new String[] { url[2] });
			// Read header
			while ((line = rdr.readLine()) != null && line.length() > 0) {
				String[] tokens = line.split(": ");
				map.put(tokens[0], new String[] { tokens[1] });
			}

			// If method 'POST' then read Content-Length worth of data
			if (url[0].equalsIgnoreCase("POST")) {
				int len = Integer.parseInt(map.get("Content-Length")[0]);
				char[] buf = new char[len];
				if (rdr.read(buf) == len) {
					line = String.copyValueOf(buf);
				}
			} else if (url[0].equalsIgnoreCase("GET")) {
				int idx = url[1].indexOf('?');
				if (idx != -1) {
					map.put("Context",
							new String[] { url[1].substring(1, idx) });
					line = url[1].substring(idx + 1);
				} else {
					line = null;
				}
			}
			if (line != null) {
				String[] match = line.split("\\&");
				for (String element : match) {
					String[] params = new String[1];
					String[] tokens = element.split("=");
					switch (tokens.length) {
					case 0:
						map.put("@".concat(element), new String[] {});
						break;
					case 1:
						map.put("@".concat(tokens[0]), new String[] {});
						break;
					default:
						String name = "@".concat(tokens[0]);
						if (map.containsKey(name)) {
							params = map.get(name);
							String[] tmp = new String[params.length + 1];
							for (int j = 0; j < params.length; j++) {
								tmp[j] = params[j];
							}
							params = null;
							params = tmp;
						}
						params[params.length - 1] = tokens[1].trim();
						map.put(name, params);
					}
				}
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		}

		return map;
	}

}
package com.ajita.httpserver;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.mina.core.buffer.IoBuffer;

public class HttpResponseMessage {
	/** HTTP response codes */
	public static final int HTTP_STATUS_SUCCESS = 200;

	public static final int HTTP_STATUS_NOT_FOUND = 404;

	/** Map<String, String> */
	private final Map<String, String> headers = new HashMap<String, String>();

	/** Storage for body of HTTP response. */
	private final ByteArrayOutputStream body = new ByteArrayOutputStream(1024);

	private int responseCode = HTTP_STATUS_SUCCESS;

	public HttpResponseMessage() {
		// headers.put("Server", "HttpServer (" + Server.VERSION_STRING + ')');
		headers.put("Server", "HttpServer (" + "Mina 2.0" + ')');
		headers.put("Cache-Control", "private");
		headers.put("Content-Type", "text/html; charset=iso-8859-1");
		headers.put("Connection", "keep-alive");
		headers.put("Keep-Alive", "200");
		headers.put("Date", new SimpleDateFormat(
				"EEE, dd MMM yyyy HH:mm:ss zzz").format(new Date()));
		headers.put("Last-Modified", new SimpleDateFormat(
				"EEE, dd MMM yyyy HH:mm:ss zzz").format(new Date()));
	}

	public Map<String, String> getHeaders() {
		return headers;
	}

	public void setContentType(String contentType) {
		headers.put("Content-Type", contentType);
	}

	public void setResponseCode(int responseCode) {
		this.responseCode = responseCode;
	}

	public int getResponseCode() {
		return this.responseCode;
	}

	public void appendBody(byte[] b) {
		try {
			body.write(b);
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	public void appendBody(String s) {
		try {
			body.write(s.getBytes());
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	public IoBuffer getBody() {
		return IoBuffer.wrap(body.toByteArray());
	}

	public int getBodyLength() {
		return body.size();
	}

}

3.封装HTTP的Server类及HTTP的Handler处理接口,其中HttpHandler接口是要暴露给外部就行自定义处理的。
package com.ajita.httpserver;

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class HttpServer {
	/** Default HTTP port */
	private static final int DEFAULT_PORT = 8080;
	private NioSocketAcceptor acceptor;
	private boolean isRunning;

	private String encoding;
	private HttpHandler httpHandler;

	public String getEncoding() {
		return encoding;
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
		HttpRequestDecoder.defaultEncoding = encoding;
		HttpResponseEncoder.defaultEncoding = encoding;
	}

	public HttpHandler getHttpHandler() {
		return httpHandler;
	}

	public void setHttpHandler(HttpHandler httpHandler) {
		this.httpHandler = httpHandler;
	}

	/**
	 * 启动HTTP服务端箭筒HTTP请求
	 * 
	 * @param port要监听的端口号
	 * @throws IOException
	 */
	public void run(int port) throws IOException {
		synchronized (this) {
			if (isRunning) {
				System.out.println("Server is already running.");
				return;
			}
			acceptor = new NioSocketAcceptor();
			acceptor.getFilterChain().addLast(
					"protocolFilter",
					new ProtocolCodecFilter(
							new HttpServerProtocolCodecFactory()));
			// acceptor.getFilterChain().addLast("logger", new LoggingFilter());
			ServerHandler handler = new ServerHandler();
			handler.setHandler(httpHandler);
			acceptor.setHandler(handler);
			acceptor.bind(new InetSocketAddress(port));
			isRunning = true;
			System.out.println("Server now listening on port " + port);
		}
	}

	/**
	 * 使用默认端口8080
	 * 
	 * @throws IOException
	 */
	public void run() throws IOException {
		run(DEFAULT_PORT);
	}

	/**
	 * 停止监听HTTP服务
	 */
	public void stop() {
		synchronized (this) {
			if (!isRunning) {
				System.out.println("Server is already stoped.");
				return;
			}
			isRunning = false;
			try {
				acceptor.unbind();
				acceptor.dispose();
				System.out.println("Server is stoped.");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		int port = DEFAULT_PORT;

		for (int i = 0; i < args.length; i++) {
			if (args[i].equals("-port")) {
				port = Integer.parseInt(args[i + 1]);
			}
		}

		try {
			// Create an acceptor
			NioSocketAcceptor acceptor = new NioSocketAcceptor();

			// Create a service configuration
			acceptor.getFilterChain().addLast(
					"protocolFilter",
					new ProtocolCodecFilter(
							new HttpServerProtocolCodecFactory()));
			acceptor.getFilterChain().addLast("logger", new LoggingFilter());
			acceptor.setHandler(new ServerHandler());
			acceptor.bind(new InetSocketAddress(port));

			System.out.println("Server now listening on port " + port);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}

package com.ajita.httpserver;

import org.apache.mina.filter.codec.demux.DemuxingProtocolCodecFactory;

public class HttpServerProtocolCodecFactory extends
		DemuxingProtocolCodecFactory {
	public HttpServerProtocolCodecFactory() {
		super.addMessageDecoder(HttpRequestDecoder.class);
		super.addMessageEncoder(HttpResponseMessage.class,
				HttpResponseEncoder.class);
	}

}

package com.ajita.httpserver;

import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

public class ServerHandler extends IoHandlerAdapter {
	private HttpHandler handler;

	public HttpHandler getHandler() {
		return handler;
	}

	public void setHandler(HttpHandler handler) {
		this.handler = handler;
	}

	@Override
	public void sessionOpened(IoSession session) {
		// set idle time to 60 seconds
		session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 60);
	}

	@Override
	public void messageReceived(IoSession session, Object message) {
		// Check that we can service the request context
		HttpRequestMessage request = (HttpRequestMessage) message;
		HttpResponseMessage response = handler.handle(request);
		// HttpResponseMessage response = new HttpResponseMessage();
		// response.setContentType("text/plain");
		// response.setResponseCode(HttpResponseMessage.HTTP_STATUS_SUCCESS);
		// response.appendBody("CONNECTED");

		// msg.setResponseCode(HttpResponseMessage.HTTP_STATUS_SUCCESS);
		// byte[] b = new byte[ta.buffer.limit()];
		// ta.buffer.rewind().get(b);
		// msg.appendBody(b);
		// System.out.println("####################");
		// System.out.println("  GET_TILE RESPONSE SENT - ATTACHMENT GOOD DIAMOND.SI="+d.si+
		// ", "+new
		// java.text.SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss.SSS").format(new
		// java.util.Date()));
		// System.out.println("#################### - status="+ta.state+", index="+message.getIndex());

		// // Unknown request
		// response = new HttpResponseMessage();
		// response.setResponseCode(HttpResponseMessage.HTTP_STATUS_NOT_FOUND);
		// response.appendBody(String.format(
		// "<html><body><h1>UNKNOWN REQUEST %d</h1></body></html>",
		// HttpResponseMessage.HTTP_STATUS_NOT_FOUND));

		if (response != null) {
			session.write(response).addListener(IoFutureListener.CLOSE);
		}
	}

	@Override
	public void sessionIdle(IoSession session, IdleStatus status) {
		session.close(false);
	}

	@Override
	public void exceptionCaught(IoSession session, Throwable cause) {
		session.close(false);
	}
}

package com.ajita.httpserver;

/**
 * HTTP请求的处理接口
 * 
 * @author Ajita
 * 
 */
public interface HttpHandler {
	/**
	 * 自定义HTTP请求处理需要实现的方法
	 * @param request 一个HTTP请求对象
	 * @return HTTP请求处理后的返回结果
	 */
	HttpResponseMessage handle(HttpRequestMessage request);
}


4.HTTP Client端,网上一抓一大把,就不说了

5.测试
建立测试类如下
package com.jita;

import java.io.IOException;

import com.ajita.httpserver.HttpHandler;
import com.ajita.httpserver.HttpRequestMessage;
import com.ajita.httpserver.HttpResponseMessage;
import com.ajita.httpserver.HttpServer;

public class TestHttpServer {
	public static void main(String[] args) throws IOException,
			InterruptedException {
		HttpServer server = new HttpServer();
		server.setEncoding("GB2312");
		server.setHttpHandler(new HttpHandler() {
			public HttpResponseMessage handle(HttpRequestMessage request) {
				String level = request.getParameter("level");
				System.out.println(request.getParameter("level"));
				System.out.println(request.getContext());
				HttpResponseMessage response = new HttpResponseMessage();
				response.setContentType("text/plain");
				response.setResponseCode(HttpResponseMessage.HTTP_STATUS_SUCCESS);
				response.appendBody("CONNECTED\n");
				response.appendBody(level);
				return response;
			}
		});
		server.run();

		//Thread.sleep(10000);
		// server.stop();
	}
}


启动,在浏览器中输入HTTP请求如:http://192.168.13.242:8080/test.do?level=aaa


附件是完整的代码。
分享到:
评论
13 楼 白天看黑夜 2017-10-20  
Apache Mina Server 2.0 中文参考手册(带目录),有需要的自己下载吧
http://www.itmayun.com/it/files/226631678709806/resource/484719910403706/1.html
12 楼 ioandy 2016-09-12  
请问楼主,为什么我在测试的时候,会收到2次请求?
11 楼 ron.luo 2016-06-12  
哥们,eclipse 部署好了,报错。
10 楼 Y412224535 2016-05-01  
引用
9 楼 Y412224535 2016-05-01  
8 楼 baiyuxiong 2014-07-09  
不错,非常好用。谢谢。
7 楼 lvyuanpeng 2014-04-03  
lvyuanpeng 写道
代码不能下载了,求大神给发个邮箱526837159@qq.com,谢谢
主要是想看看HttpResponseEncoder
6 楼 lvyuanpeng 2014-04-03  
代码不能下载了,求大神给发个邮箱526837159@qq.com,谢谢
5 楼 Ajita 2014-03-09  
slipper-jay 写道
但是要分发多个handler处理该怎么做呢?

自己写if-else分别处理
4 楼 slipper-jay 2014-03-07  
但是要分发多个handler处理该怎么做呢?
3 楼 Ajita 2014-02-26  
slipper-jay 写道
缺少HttpResponseEncoder啊  能发一下吗

你好,请下载文章的附件,里面应该有!
2 楼 slipper-jay 2014-02-24  
缺少HttpResponseEncoder啊  能发一下吗
1 楼 hayoouch 2012-08-03  
谢谢,学习了

相关推荐

    MinaServer for Android

    MinaServer是一款专为Android平台设计的服务端应用程序,它基于Apache Mina框架构建,允许开发者在Android设备上实现高性能、低延迟的网络通信服务。Mina是一个开源项目,旨在简化网络应用开发,尤其适用于TCP/IP和...

    mina客户端服务器简易Demo

    首先,让我们来看看“minaServer”部分。Mina服务器端主要负责监听网络连接、接收客户端请求并发送响应。在这个Demo中,服务器端通常会包含以下组件: 1. **ServerBootstrap**: 这是服务器启动的核心类,用于配置...

    Mina server client实例

    **minaclient.PNG 和 minaserver.PNG** 这两个文件可能是示例程序的截图,可能展示了Mina Server和Mina Client运行时的界面或状态,帮助开发者直观地理解它们的工作方式和交互过程。 **minaClient 和 MinaServer** ...

    Mina2.0 example HttpServer

    以上代码展示了如何使用Mina2.0创建一个简单的HttpServer,MyHandler是我们自定义的事件处理器,负责处理接收到的HTTP请求和可能出现的异常。 通过阅读和分析Mina2.0的源码,我们可以更深入地理解其内部工作机制,...

    MINA 服务端和客户端demo

    在"minaServer.rar"和"minaClient.rar"这两个压缩包中,分别包含了服务端和客户端的源代码示例。通过学习和运行这些示例,你可以深入了解MINA如何工作,以及如何利用MINA快速开发自己的网络应用。在实际项目中,可以...

    mina server开发服务端/客户端代码

    本压缩包包含的是使用Mina Server开发的服务端和客户端的源代码示例,非常适合初学者和有经验的开发者用来学习和参考。 服务端开发: 在Mina中,服务端通常通过创建一个Acceptor来监听特定的端口,等待客户端的连接...

    java 实现的mina server client完全能用的

    这个“java 实现的mina server client完全能用的”项目可能包含了一个完整的Mina服务器和客户端实现,使得开发者能够快速构建基于TCP或UDP的网络应用。 在Java Mina中,Server是服务端,它监听特定的端口,等待...

    Apache_Mina_Server_ 深入教程V1.0

    Apache Mina Server是一款高性能且易于使用的网络通信应用框架,主要基于TCP/IP和UDP/IP协议栈进行设计,同时也支持其他类型的通信服务,比如JAVA对象的序列化服务、虚拟机间的管道通信服务等。该框架的核心优势在于...

    Mina开发实例(服务端、客户端)DEMO

    Maven帮助开发者管理依赖,使得引入和更新Mina库以及其他相关库变得简单。在`pom.xml`文件中,可以看到对Mina库的依赖声明,以及项目的构建配置。 为了实现长连接通讯,Mina提供了保持连接活跃的机制。通常,心跳...

    Apache_Mina_Server_2.0中文参考手册

    7. **跨平台性**:由于基于Java开发,Apache Mina Server 2.0可以在任何支持Java的平台上运行,包括Windows、Linux、Mac OS等,具备良好的跨平台兼容性。 8. **可配置性**:Mina允许开发者通过XML配置文件或者代码...

    基于mina的及时通信

    1. **服务器端**:使用Mina作为底层通信框架,创建Socket服务监听客户端的连接请求。当有新的连接建立时,分配一个Session,并通过过滤器链处理客户端发送过来的数据。服务器端还需要实现消息的广播机制,确保消息能...

    Android-基于ApacheMINA进行封装实现AndroidAPP作为服务器客户端进行通讯

    - **初始化客户端**:创建一个IoConnector实例,配置目标服务器的地址和端口,以及IoHandler,然后发起连接请求。 - **编写过滤器**:根据需求创建自定义过滤器,处理数据收发前后的逻辑,如数据加密、压缩等。 -...

    Apache_Mina_Server中文参考手册.pdf

    Apache Mina Server是一款基于Java的高性能、可扩展的网络通信应用框架。它支持TCP/IP和UDP/IP协议栈通信,并且可以提供Java对象序列化服务、虚拟机管道通信服务等多种功能。Mina框架的核心设计思想是使用事件驱动、...

    Apache_Mina_Server_2.0V1.0.rar_mina

    4. **服务端和客户端接口**:手册将详细介绍如何使用Mina API创建服务端和客户端,包括设置监听端口、处理连接请求、接收和发送数据等步骤。 5. **异常处理和日志系统**:Mina提供了完善的异常处理机制,帮助开发者...

    Apache_Mina_Server_2.0.rar_mina

    7. **实战教程**:创建MINA服务器和客户端的步骤,以及如何处理网络请求和响应。 8. **异常处理**:在MINA中如何捕获和处理网络通信中的异常情况。 9. **扩展性**:MINA的模块化设计使得添加新功能和集成其他库变...

    Apache.Mina.Server.2.0.中文参考手册_李海峰

    Apache Mina Server是一款高性能、易于使用的网络通信框架,主要用于构建基于TCP/IP或UDP/IP协议的应用程序。该框架的核心优势在于其能够帮助开发者快速构建高效且可扩展的网络服务。Mina支持事件驱动和异步编程模型...

    Apache_Mina_Server_ 深入教程

    本教程将深入探讨Apache Mina Server的核心概念、设计模式以及实际应用,帮助读者掌握其强大的功能。 1. **Mina架构与设计理念** Apache Mina采用了事件驱动和异步I/O的模型,这种模型使得Mina在处理大量并发连接...

    Apache_Mina_Server_2.0中文参考手册V1.0.pdf

    Apache Mina Server是一个高性能、可扩展的网络通信应用框架,主要用于基于TCP/IP和UDP/IP协议栈的通信框架开发。它不仅支持网络通信,还可以提供JAVA对象序列化服务和虚拟机管道通信服务等。Mina通过提供事件驱动和...

    XMPP与MINA

    SocketAcceptor是MINA中的核心组件,用于监听和接受来自客户端的连接请求。接着,Openfire定制了ExecutorThreadModel,这是一个线程池模型,用于处理接收到的数据 stanza。线程池大小根据JiveGlobals属性进行配置,...

Global site tag (gtag.js) - Google Analytics