首先很佩服自己的意志啊。竟然能在第二天做到继续开写博客。哇哈哈哈。
到处找人咨询啊,找群求助啊,发现身边竟然没有人做过TCP协议的项目唉。我瞬间发现啊,我认识的做技术的人太少了。
偶然听说的这个mima框架啊。伟大的硬哥推荐啊。一下解决了我的session问题(昨儿个纠结的)。我只知道mima能干很多事,只是现在我只用到了这个。剩下的以后再来研究吧。。。。。。
下载jar包。省去200字。百度一下你就知道。一个mima的核心包,一个slf4j-api ,再来一个自己的log4j就ok了。
。。。。。。。。。
然后开始写服务端的代码了。
建立一个项目叫做MInaServer。代码如下:
package mina;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
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.NioSocketAcceptor;
public class MinaSimpaleServer {
private static final int PORT = 5678;
public static void main(String[] args)throws IOException{
// 创建一个非阻塞的服务器端的Socket
IoAcceptor acceptor = new NioSocketAcceptor();
// 设置过滤器
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codex", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
// s设置逻辑处理器
acceptor.setHandler(new SimpaleServerHandler());
// s设置缓冲区的大小
acceptor.getSessionConfig().setReadBufferSize(1024*1024);
// 设置多久进入空闲状态
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
// 绑定端口
acceptor.bind(new InetSocketAddress(PORT));
System.out.println("服务器已启动,端口号为:" + PORT);
}
}
对于我这个层次的连菜鸟都不算的人来说,这个代码顺序,流程,直接不需要改,甚至不需要明白(当然注释已经很清楚了)。你只需要知道怎么设置逻辑处理器就ok了。剩下的就去改一下逻辑处理器的接收到传入参数后执行的方法就完事了。亲们啊,这就完事了。信不?
那我们就建一个逻辑处理的类,这个类需要extend一下mina的IoHandlerAdapter类。这里面的方法就是处理请求的,从传入到传出的过程都有处理。
override一下里面的messageReceived方法,这个方法呢,就是接收到请求数据调用的方法。你就可以在这里实现你自己的业务了。
package mina;
import java.util.Date;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
public class SimpaleServerHandlerextends IoHandlerAdapter{
//捕捉到异常后调用的
public void exceptionCaught(IoSession session, Throwable cause)throws Exception{
cause.printStackTrace();
session.write("Iliagal input");
}
// 接收到消息后调用的
public void messageReceived(IoSession session, Object message) throws Exception{
String strMsg = message.toString();
if(strMsg.trim().equalsIgnoreCase("quit")){
session.close();
return;
}
String retMsg = "7878";
if(strMsg != null && !"".equals(strMsg)){
if("7878".equals(strMsg.substring(0, 4))){
if("01".equals(strMsg.substring(6, 8))){
//登录
System.out.println("登陆操作");
retMsg += "0501";
session.setAttribute("isLogin", "1");
}else if("13".equals(strMsg.substring(6, 8))){
//退出
System.out.println("退出");
retMsg += "05e3";
}else{
System.out.println("不知道干什么");
retMsg += "1111";
}
}else{
retMsg += "0000";
}
}else{
retMsg += "0000";
}
System.out.println("login状态-----" + session.getAttribute("isLogin"));
retMsg += "0d0a";
Date date = new Date();
session.write(date.toString() + "------" + retMsg);
System.out.println("Message written...");
}
public void sessionIdle(IoSession session, IdleStatus status)throws Exception{
System.out.println("IDLE..." + session.getIdleCount(status));
}
// 这个方法是在服务器发送消息成功后调用的
@Override
public void messageSent(IoSession session, Object message) throws Exception {
super.messageSent(session, message);
}
}
最后声明下,刚知道的一件事情啊,当前这种实现,是一种长连接的方式啊。如果你要实现短连接,在服务器端操作很简单,只需要在发送完数据后,把链接断掉就好了啊。so,只需要在messageSent方法里,加入session。close()了。
对了还是session的情况。一般TCP协议传入的参数不会像一般的客户端一样需要自己记录登录信息(账户密码),每次登陆的时候都去校验登陆。这里实现呢,就是session来记录登录状态。当登陆时,我们根据session的setAttribute方法来设置一个参数或者几个参数,只要i需要,随你便。这样session就记录了。因为一个硬件请求只会有一个session的。
today 就到这里。。。。。。