Spring2.5+MINA2搭建Socket Server

1、下载相应的开发包http://mina.apache.org/,MINA2.0版本包含了spring开发包,还需下载其他相关包,我的工程用到的包如下图:

     

2、配置spring的spring-mina-1.xml,配置mina服务:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
						http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	<!-- mina server -->
	<bean id="serverHandler" class="minaT5.ServerHandler" />

	<!-- executorFilter多线程处理 -->
	<bean id="executorFilter" class="org.apache.mina.filter.executor.ExecutorFilter" />

	<bean id="mdcInjectionFilter" class="org.apache.mina.filter.logging.MdcInjectionFilter">
		<constructor-arg value="remoteAddress" />
	</bean>

	<bean id="codecFilter" class="org.apache.mina.filter.codec.ProtocolCodecFilter">
		<constructor-arg>
			<!-- <bean class="org.apache.mina.filter.codec.textline.TextLineCodecFactory" 
				/> -->
			<!-- 处理对象流时候用ObjectSerializationCodecFactory -->
			<!-- <bean class="org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory" 
				/> -->
			<bean class="minaT5.ServerCodeFactory" />
		</constructor-arg>
	</bean>

	<bean id="loggingFilter" class="org.apache.mina.filter.logging.LoggingFilter" />

	<bean id="filterChainBuilder"
		class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder">
		<property name="filters">
			<map>
				<entry key="executor" value-ref="executorFilter" />
				<entry key="mdcInjectionFilter" value-ref="mdcInjectionFilter" />
				<entry key="codecFilter" value-ref="codecFilter" />
				<entry key="loggingFilter" value-ref="loggingFilter" />
			</map>
		</property>
	</bean>
	
	<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
		<property name="customEditors">
			<map>
				<entry key="java.net.SocketAddress">
					<bean class="org.apache.mina.integration.beans.InetSocketAddressEditor" />
				</entry>
			</map>
		</property>
	</bean>
	
	<bean id="ioAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor"
		init-method="bind" destroy-method="unbind">
		<property name="defaultLocalAddress" value="127.0.0.1:1235" />
		<property name="handler" ref="serverHandler" />
		<property name="filterChainBuilder" ref="filterChainBuilder" />
		<property name="reuseAddress" value="true" />
	</bean>
</beans>

3、ServerHandler实现类

package minaT5;

import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.apache.log4j.Logger;
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 final int IDLE = 300;

	private final Logger log = Logger.getLogger(ServerHandler.class);

	private static Set<IoSession> sessions = Collections.synchronizedSet(new HashSet<IoSession>());

	/**
	 * 
	 */
	public ServerHandler() {

	}

	@Override
	public void exceptionCaught(IoSession session, Throwable cause) {
		session.close();
		// log.debug("session occured exception, so close it.");
		log.info("session occured exception, so close it."
				+ cause.getMessage());
	}

	@Override
	public void sessionCreated(IoSession session) {
		log.info("remote client [" + session.getRemoteAddress().toString()
				+ "] connected.");
		session.write("welcome");
		sessions.add(session);
	}

	@Override
	public void messageReceived(IoSession session, Object message) {
		String str = message.toString();
		log.info("Message written " + str);
		log.info("客户端"
				+ ((InetSocketAddress) session.getRemoteAddress()).getAddress()
						.getHostAddress() + "连接成功!");
		/*
		 * if (str.trim().equalsIgnoreCase("quit")) { session.close();// return;
		 * }
		 */
		// Date date = new Date();
		// session.write(date.toString());//
		// session.setAttribute(remoteAddress, message);
		session.setAttribute("type", message);
		String remoteAddress = ((InetSocketAddress) session.getRemoteAddress())
				.getAddress().getHostAddress();
		session.setAttribute("ip", remoteAddress);
	}

	@Override
	public void sessionClosed(IoSession session) {
		log.info("sessionClosed.");
		sessions.remove(session);
	}

	@Override
	public void sessionIdle(IoSession session, IdleStatus status) {
		log.info("session idle, so disconnecting......");
		session.close();
		log.info("disconnected.");
	}
	
	@Override
	public void messageSent(IoSession session, Object message){
		  log.info("messageSent.");  
	        // disconnect an idle client  
	        //session.close();  
	}
	
	@Override
	public void sessionOpened(IoSession session){
		 log.info("sessionOpened.");  
	        //  
		 session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, IDLE);
	}
}

4、过滤器ServerCodeFactory

package minaT5;

import java.nio.charset.Charset;

import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineDecoder;
import org.apache.mina.filter.codec.textline.TextLineEncoder;

public class ServerCodeFactory implements ProtocolCodecFactory{

	private final TextLineEncoder encoder;
	private final TextLineDecoder decoder;
	
	/*final static char endchar = 0x1a;*/  
    final static char endchar = 0x0d;
    
    public ServerCodeFactory(){
    	this(Charset.forName("UTF-8"));
    }
    
	public ServerCodeFactory(Charset charset) {
		encoder = new TextLineEncoder(charset, LineDelimiter.UNIX);
		decoder = new TextLineDecoder(charset, LineDelimiter.AUTO);
	}

	

	@Override
	public ProtocolDecoder getDecoder(IoSession arg0) throws Exception {
		return decoder;
	}

	@Override
	public ProtocolEncoder getEncoder(IoSession arg0) throws Exception {
		return encoder;
	}

	public int getEncoderMaxLineLength(){
		return encoder.getMaxLineLength();
	}
	
	public void setEncoderMaxLineLength(int maxLineLength){
		encoder.setMaxLineLength(maxLineLength);
	}
	
	public int getDecoderMaxLineLength(){
		return decoder.getMaxLineLength();
	}
	
	
	public void  setDecoderMaxLineLength(int maxLineLength){
		decoder.setMaxLineLength(maxLineLength);
	}
}

5、启动spring+mina socket server;

package minaT5;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-mina-1.xml");
		
	}
}

6、客户端测试ClintTest

package minaT5;

import java.net.InetSocketAddress;

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

public class ClintTest {
	public static void main(String[] args) {
		NioSocketConnector connector = new NioSocketConnector();
		connector.getFilterChain().addLast("logger", new LoggingFilter());
		 //connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "GBK" )))); //  
        connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory()));
        connector.setConnectTimeout(1);
        connector.setHandler(new ServerHandler());
        ConnectFuture cf = connector.connect(
        		new InetSocketAddress("localhost", 1235));
        cf.awaitUninterruptibly();
        cf.getSession().write("hello,测试!");
        //cf.getSession().write("quit");//  
//        cf.getSession().close();  
        cf.getSession().getCloseFuture().awaitUninterruptibly();//  
//        connector.dispose();   
	}
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值